【问题标题】:Roblox Script Builder SandboxRoblox 脚本生成器沙盒
【发布时间】:2015-10-22 15:49:02
【问题描述】:

我最近开始创建脚本生成器。我唯一坚持的部分是让沙箱工作。

我尝试按照本教程进行操作:http://wiki.roblox.com/index.php?title=Sandboxing 但无济于事

我不完全了解如何做到这一点,但我设法做到了这一点:

local needssandboxing = function(i) end

sandbox = {}
sandbox.cache = {}

local function safeDestroy(obj)
    if obj.ClassName == "Script" then
        print("You cannot destroy a Script")
    elseif obj == "Base" then
        print("You cannot destroy the Base.")
end 


    obj:Destroy()
end

local function safeGetChildren(obj)
    local res = {}

    for k,v in pairs(obj:GetChildren()) do
    if not v.Name:match("^Hide") then
            table.insert(res,v)
        end
    end

    return res
end

sandbox.mt = {
    __index = function(self, k)
        local original = sandbox.cache[self]
        local v = original[k]

        if k:lower() == "destroy" then
            return sandbox.any(safeDestroy)

        elseif k:lower() == "getchildren" or k:lower() == "children" then
            return sandbox.any(safeGetChildren)
        end

        return sandbox.any(v)
    end,

    __newindex = function(self, k, v)
        local original = sandbox.cache[self]
        original[k] = unsandbox.any(v)
    end
}

function sandbox.any(a)
    if sandbox.cache[a] then
        return a

    elseif type(a) == "function" then
        return sandbox.func(a)

    elseif type(a) == "table" then
        return sandbox.table(a)

    else
        return value
    end
end

function sandbox.object(o)
    local sandboxed = setmetatable({}, sandbox.mt)

    sandbox.cache[sandboxed] = o

    return sandboxed
end

function sandbox.func(f)
    local sandboxed = function(...)
        return sandbox(f(unsandbox(...)))
    end

    sandbox.cache[sandboxed] = f

    return sandboxed
end

function sandbox.table(t)
    local sandboxed = {}

    for k, v in pairs(t) do
        sandboxed[sandbox.any(k)] = sandbox.any(v)
    end

    return sandboxed
end

unsandbox = {}

unsandbox.any = function(a)
    if sandbox.cache[a] then
        return sandbox.cache[a]

    elseif type(a) == "function" then
        return unsandbox.func(a)

    elseif type(a) == "table" then
        return unsandbox.table(a)

    else
        return a
    end
end

unsandbox.table = function(t)
    local unsandboxed = {}

    for k, v in pairs(t) do
        unsandboxed[unsandbox.any(k)] = unsandbox.any(v)
    end

    return unsandboxed
end

unsandbox.func = function(f)
    local raw = function(...)
        return unsandbox(f(sandbox(...)))
    end

    sandbox.cache[f] = raw 

    return raw
end

local callable_mt = {
   __call = function(self, first, ...)
       if select('#', ...) == 0 then
           return self.any(first)
       else
           return self.any(first), self(...)
       end
   end
}

setmetatable(sandbox, callable_mt)
setmetatable(unsandbox, callable_mt)

但我不知道如何准确地使用它。我试过了:

sandbox(function() 
    local r = game.Workspace:GetChildren()
    for i=1, #r do
        print(r[i])
    end
end)

那绝对没有任何作用。是不是我做错了什么?

【问题讨论】:

    标签: roblox


    【解决方案1】:

    在你的代码中,没有函数sandbox(),所以你试图调用一个不存在的函数。

    试试这个:

    sandbox.func(function()
        local r = game.Workspace:GetChildren()
        for i=1, #r do
            print(r[i])
        end
    end)
    

    【讨论】:

      【解决方案2】:

      沙盒本身不是一个函数,但 __call 元方法允许它作为一个函数被调用,即使它是一个表。

      您的代码必须放在包含以下代码的脚本中。 然后,当您希望加载脚本时,将名为“Code”的 StringValue 放入脚本中,并将 Value 属性设置为您希望执行的脚本:

      local realEnvironment = getfenv(0);
      local fakeEnvironment = setmetatable({}, {__index = function (self, i)
          if (realEnvironment[i]) then --Check if object exists at all
              return sandbox(realEnvironment[i]) --return sandboxed object
          end;
      end, __metatable = 'This is a locked metatable!'}); --An environment to only return sandboxed objects
      setfenv(0,fakeEnvironment);--Set the global environment 
      setfenv(1,fakeEnvironment);--Set the current function stack
      assert(loadstring(script:WaitForChild('Code').Value))();
      

      最后一行等待 'Code' child,然后在其上调用 loadstring,assert 将检查它是否有语法错误,如果有,则会出错,如果没有,则返回随后调用的函数 (不需要设置函数的ENV,因为我们设置了全局环境)。

      【讨论】:

        猜你喜欢
        • 2016-04-21
        • 1970-01-01
        • 2013-05-09
        • 2011-05-31
        • 1970-01-01
        • 1970-01-01
        • 2020-09-26
        • 2018-06-17
        • 2013-10-02
        相关资源
        最近更新 更多