脚本功能

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

脚本能力是一个系统,可以提供控制脚本在 DataModel 子树下可以执行的动作。它提供更好的控制体验脚本,而不是一个“所有或无”系统,在哪个脚本都可以做任何其他脚本可以做的事情。

  • 此系统允许您限制从工具箱中取得的模型可以做的事情,并且使用户生成内容更容易包含在体验中,即使包含脚本。
  • 它还可以帮助确保允许玩家运行自己的验证码的体验的更好安全性,这通常在限制或模拟环境中执行。
  • 它还可以用于共享限制自己所能做的图书馆。例如,提供额外的数学方法的图书馆可以被限制为仅包含最小限度的功能,以便其他使用该图书馆的开发者不必验证整个代码库以确保它不包含恶意验证码。

启用脚本功能

要启用此精选,改变 SandboxedInstanceMode 设置从 DefaultExperimental 在 Explorer 中。

客户端测试完成后,此步骤将不再需要。

沙盒容器

此系统介绍一个名为 沙箱容器 的概念。一个 Model 实例, Folder , 1> Class.Script1> 或其他那些类型的后代都有一个 4> Class.Instance.Sandboxed|Sandbox

Sandboxed property of a Folder in the Properties window.

启用 Sandboxed 属性将实例设置为一个沙箱容器,其中 DataModel 树的树中,限制脚本中的脚本可以根据 Capabilities 属性的设置执行的行动。

能力

Capilities 属性是一个控制不同执行层次的执行、分为四个组的值集:

  • 执行控制 - 指定脚本是否可以在客户机或服务器上运行
  • 实例访问控制 - 指定脚本可以与哪些 DataModel 零件交互
  • 脚本功能控制 - 指定哪些 Luau 脚本可以调用
  • 引擎 API 访问控制 - 指定 Roblox 引擎 API 的哪些部分可以用

当脚本尝试执行当前执行状态下不在能力集中的操作时,会发生错误。错误通常包括正在尝试执动作的操作、目标和第一个可用的能力,例如:


The current thread cannot modify 'Workspace' (lacking capability AccessOutsideWrite)
The current thread cannot call 'Clone' (lacking capability CreateInstances)
The current thread cannot call 'GetSecret' (lacking capability Network)

执行控制

此套件包括两个能力:

  • 运行客户端脚本 - LocalScriptScript 使用 0> Class.BaseScript.RunContext|RunContext0> 值的 3> Class.EnumerateRunContext.Client|Client 3> 允许在客户端上运行
  • 运行服务器脚本 - Script 使用 RunContext 值的 0> 枚.RunContext.Server|Server0> 可以在服务器上运行

如果脚本是 Enabled ,但与该位置相对应的能力不可用,警告消息会在 输出 窗口中显示。如果脚本不应该在该上下文中运行,请禁用或删除它。

注意,ModuleScripts 不需要有这些执行功能才能要求。

当脚本因执行控制功能缺失而无法启动时,它将被报告为警告在输出中,例如:


Cannot start server script 'Script' (lacking capability RunServerScript)

实例访问控制

此集合包含仅一个能力:

  • 使用外部文本写入脚本 - 脚本可以从沙盒容器外部获取和接收实例

当可能性不可用时,脚本只能查找位于其自己的沙盒容器内的实例。例如,如果脚本直接放置在沙盒容器中,script.Parent.Parent 返回nil

此外,任何 Roblox API 事件通过在 Instance 而不是在 nil 通过任何 Instance 外的容器传入。例如,如果在沙盒容器外的任何 2> Class.Instance2> 被触摸,5> nil

避免设置此功能;沙盒保证在体验中与任何实例互动时都会更弱。

访问服务

即使没有 AccessOutsideWrite ,在沙盒容器中的脚本仍然可以访问 gameworkspace 和服务。这种访问提供使脚本仍然可以调用这些全球的有用方法,例如 1> Class.DataModel.GetService1> ,但仍然验证了他们的子实例。

内部通过实例

如果实例通过 Roblox API 不通过,该引用将被保留。 但如果通过 ModuleScript 这样传入,它不能需要使用 AccessOutsideWrite 。 这是因为 ModuleScript 的返回通常是可变的,并且可以被在沙盒容器中的脚本修改。

脚本功能控制

这套能力控制一些脚本的一般方面:

请注意,默认函数限制仍然适用。即使 LoadString 已启用,体验仍然需要在 ServerScriptService 中启用它,并且它仍然只会在服务器上可用。

要创建新实例,除了 创建实例 之外,还需要一个额外的引擎 API 功能,可以提供访问该实例。

引擎 API 访问控制

这个最后的能力组控制脚本访问各个引擎 API:

  • 基础 - 访问简单实例和必需的建筑块
  • 音频 - 访问与音频 API 相关的实例
  • 数据存储 - 访问数据存储和内存存储 API
  • 网络 - 访问 HTTP 网络 API
  • 物理学 - 访问与物理学相关的实例
  • UI - 访问与用户界面相关的实例
  • CSG : 访问与建造有关的实例和函数(CSG)
  • 聊天 : 访问与体验聊天相关的实例
  • 动画 :访问有关动画的实例
  • 虚拟形象 : 访问与虚拟形象相关的实例
  • 输入 :访问与用户输入相关的实例
  • 环境 :访问与环境显示有关的实例
  • 远程事件 : 访问内部网络操作的实例

还有一些例子可以无需执行脚本就可以使用。这些例子包括以下 HttpService 方法:

如果实例属性或方法访问不了所需的能力,会报告一个错误,描述所缺少的能力。

最后,功能今天在 Roblox 引擎中不覆盖每个实例。不列出在此部分或下一个部分中的实例不可用于沙盒容器中的交互,并且在当前脚本中不可用的 未分配 功能不可用于当前脚本。

额外的限制是,getfenvsetfenv 功能对于沙盒容器中的脚本不可用。

仅脚本访问实例是有限的。实例本身仍然可以存在并运行在一个沙盒容器内。灯仍然会发光,用户界面仍然可以显示,音频设置已经连接播放声音。

引擎 API 能力分配

这是每个 API 功能的实例和方法列表(如果与实例功能不同):

容器之间的交互

子容器

当一个沙箱容器被另一个容器子沙箱容器中时,内部容器的实例可以访问到外部容器。

内部容器的能力受到外部容器的能力的限制。例如,如果外部容器具有 基础音频CSG 的能力,而内部容器具有1>基础1>和4>网络4>,那么,在执行时间时,内部容器只能使用7>基础7>容器的能力。

如果内部和外部容器之间没有任何可能,那么结果的容量设置将为空。

可绑定的函数和事件

BindableEventBindableFunction 提供最佳方式与容器通信,或允许它直接使用的能力,或允许它直接使用的能力。

当发生事件或函数时,连接将在注册它们的函数上下文中执行。 这意味着如果事件或函数回调由沙盒容器注册,它将被调用以使用该容器的功能。如果代码在外部注册,当沙盒容器脚本邀请它时,它将执行您的函数以使用可用于您的函数的功能。

注意,即使具有 AccessOutsideWrite 功能,沙箱容器中的脚本不能在容器自身之外调用事件或函数,如果它们的容量设置超过容器自身。

模块要求

内部 ModuleScripts 可以由沙箱容器要求。如果目标实例位于容器外,则 ModuleScript 只能要求,如果能力集对象小于或等于容器可用能力集,才能要求。

此限制不适用于 RunClientScriptRunServerScript 功能。如果 ModuleScript 放置在只有 1> RunClientScript1> 的容器中,但是需要从有 4> RunServerScript4> 功能的脚本中运行,那么它就允许成功并在服务器上运行这些功能。

直接调用函数

如果需要从容器中的 ModuleScript 在外部容器中,一些保护不可用。例如,目标函数无法访问可用给调用者的所有实例。如果调用者不在沙箱中,调用将作为 访问外部写入 可用。

其他技能限制仍然适用。如果您有一个 数据存储 访问能力,但目标模块不是,它将无法调用 DataStore 方法。 但如果您通过自己的函数使用 DataStore ,目标可以在该调用期间运行。如果您通过

实例可以传递到目标模块或分配到模块田。

如果需要,请使用 rawset 来分配表成员,以避免运行 __index / __newindex 上的 metamethodes 可能会在表上设置。

总体建议是尽可能使用 BindableEventBindableFunction

实例的移动

大多数实例不会在容器之间有限制。 但脚本实例可以只能移动到具有相同集合 of 功能或子集 of 功能的容器。

这意味着使用 AccessOutsideWrite 的沙箱容器无法只是在其内部重新父级化一个脚本以外部并获得更多功能。