Lua ROBLOX沙箱

Lua ROBLOX沙箱,lua,roblox,Lua,Roblox,我不熟悉Lua中的沙箱,希望学习如何过滤诸如:GetChildren()或:Kick()之类的内容 这就是我到目前为止所做的: function safeGetChildren(obj) local objs = {} for _,v in pairs(obj) do if not v.Name:match("^^") then table.insert(objs, v.Name) end end retu

我不熟悉Lua中的沙箱,希望学习如何过滤诸如:GetChildren()或:Kick()之类的内容

这就是我到目前为止所做的:

function safeGetChildren(obj)
    local objs = {}
    for _,v in pairs(obj) do
        if not v.Name:match("^^") then
            table.insert(objs, v.Name)
        end
    end

    return objs
end

function safeClearAllChildren(obj)
    if obj:IsA("Player") or obj:IsA("Players") or obj:IsA("Workspace") or obj:IsA("ServerScriptService") or obj:IsA("Lighting") or obj:IsA("ReplicatedStorage") or obj:IsA("StarterGui") then
        return error("Cannot clear this object!");
    else
        obj:ClearAllChildren();
    end
end

function safeRemoveObject(obj)
    local name = obj.Name:lower();

    if obj:IsA("Player") or  name == "remoteevents" or obj.Parent == "RemoteEvents" or obj.Parent == "ReplicatedStorage" or obj.Parent == "StarterGui" or obj.Parent == "ServerScriptService" or obj.Parent == "TinySB" then
        return error("Cannot destroy this object!");
    else
        obj:Destroy();
    end
end

local Globals = {
    -- Globals
    workspace = workspace,
    print = print,
    error = error,
    table = table,
    pairs = pairs,
    game = game,
    string = string,
    _G = _G,
    getfenv = getfenv,
    loadstring = loadstring,
    ipairs = ipairs,
    next = next,
    os = os,
    pcall = pcall,
    rawequal = rawequal,
    rawget = rawget,
    rawset = rawset,
    select = select,
    setfenv = setfenv,
    setmetatable = setmetatable,
    tonumber = tonumber,
    tostring = tostring,
    type = type,
    unpack = unpack,
    _VERSION = _VERSION,
    xpcall = xpcall,
    collectgarbage = collectgarbage,
    assert = assert,
    gcinfo = gcinfo,
    coroutine = coroutine,
    string = string,
    table = table,
    math = math,
    delay = delay,
    LoadLibrary = LoadLibrary,
    printidentity = printidentity,
    spawn = spawn,
    tick = tick,
    time = time,
    UserSettings = UserSettings,
    Version = Version,
    wait = wait,
    warn = warn,
    ypcall = ypcall,
    PluginManager = PluginManager,
    LoadRobloxLibrary = LoadRobloxLibrary,
    settings = settings,
    stats = stats,

    -- Functions
    ["require"] = function(...)
        return error("Cannot require object (API disabled)");
    end,
    ["getchildren"] = function(...)
        return safeGetChildren(...);
    end,
    ['children'] = function(...)
        return safeGetChildren(...);
    end,
    ['clearallchildren'] = function(...)
        return safeClearAllChildren(...);
    end,
    ['destroy'] = function(...)
        return safeRemoveObject(...);
    end,
    ['remove'] = function(...)
        return safeRemoveObject(...);
    end,
    ['kick'] = function(...)
        return safeRemoveObject(...);
    end,
    ['saveplace'] = function(...)
        return error("Cannot save place (API Disabled)");
    end
}
setfenv(1, Globals)
table.foreach(workspace:GetChildren(), print)

我在几个小时内完成了这项工作,但在这种环境中不会过滤诸如:GetChildren()之类的内容。如果有人能帮我解释一下所需代码的每一部分的作用,那将非常有用。

您正在新环境中以“getchildren”的名称设置安全包装器。但稍后,在测试时,您将调用“GetChildren”,它取自“workspace”表,而不是新环境中的全局变量。

在全局环境中替换函数并不意味着在所有表/对象中替换具有相同名称的函数。要实现这一点,对象必须从当前全局环境调用函数,而不是从内部表或词法闭包调用函数。

您必须包装每个对象。如何包装对象?这既复杂又广泛。但基本上你用一个表来替换每个表,并使用_索引和_新索引来处理获取/设置成员。你能将我链接到文档以便我可以学习吗?我不相信它们是官方文档,但如果你在roblox(warspyking)上PM我,我肯定会给你更详细的解释。但就目前而言,这个问题可能有点太复杂了,我建议接受vlad的回答,你能举个例子吗?@Jacob,我不知道workspace:GetChildren()的确切实现是什么。但若您只想通过替换全局环境来对其进行沙盒处理,那个么它本身必须是一个包装器,调用全局函数。比如说,
函数工作区:GetChildren(…)返回GetChildren(…)end
,并且GetChildren必须放在全局环境中。好的libs不会污染globalenv的内部结构,所以事实并非如此。我该如何使用p:GetChildren()之类的东西呢?类似的事情也会发生吗?如果实现允许,您必须在实际的“p”实例中替换p:GetChildren()。比方说,如果“p”是一个表,您可以分配
p.GetChildren=safeGetChildren
。但有时,如果“GetChildren”来自metatable,这是不可能的。