腳本功能

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

腳本功能 是一個系統,可以對腳本在DataModel內執行的行動提供控制。它提供更好的控制經驗腳本,而不是成為「全部或無」系統,其他腳本可以做任何其他腳本可以做的事情。

  • 這個系統讓你限制工具箱中擷取的模型可以做的事情,並讓包含使用者生成內容的體驗更容易包含包含腳本的內容。
  • 它也可以幫助確保允許玩家執行自己的代碼的體驗的更好安全,這通常在受限或模擬環境中執行。
  • 它也可以用來分享限制自己能做什麼的圖形庫。例如,提供額外數學方法的圖書館可以限制到最小的功能集,以確保其他使用該圖書館的開發人員不需要驗證整個代碼庫來確保它不包含惡意代碼。

啟用腳本功能

要啟用此功能,請在 Explorer 中將 SandboxedInstanceMode 設定從 Default 變更為 Experimental

當客戶 beta 測試完成時,此步驟將不再需要。

沙盒容器

這個系統引入了一個 沙盒容器 的概念。類型 ModelFolderScript 或這些類別的後裔有在 Studio Sandboxed 窗口中可用的 **** 屬性,在 權限 部分。

Sandboxed property of a Folder in the Properties window.

啟用 Sandboxed 屬性將指定實例作為沙盒容器內的 DataModel 樹中的容器,這會限制內容樹中的腳本可以執行的操作,根據 Capabilities 屬性集的值來執行。

能力

Capabilities 屬性是一組控制執行不同方面的值,分為四個組:

  • 執行控制 - 指定是否可以在客戶端或伺服器上執行腳本
  • 實例存取控制 - 指定腳本可與哪些 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)

執行控制

此集包括兩個能力:

如果腳本是 Enabled ,但對應的位置無法啟動的能力不可用,在 輸出 窗口中會顯示警告訊息。如果腳本不應在該上下文中運行,請停用或刪除它。

請注意,ModuleScripts 不需要擁有這些執行功能才需要。

當執行控制功能缺少時,導致腳本無法啟動時,將在輸出中報告為警告,例如:


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

實例存取控制

此集只包含一個能力:

  • 寫入外部訪問 - 腳本可以從沙盒容器之外獲取和接收實例

當能力無法使用時,腳本只能查找屬於自己沙盒容器內的實例。例如,如果腳本直接放置在沙盒容器中,script.Parent.Parent返回nil

此外,任何 Roblox API 事件,如果傳入 Instance 而不是傳入 nil 到沙盒中的容器外部,都會傳入 Instance 。例如,如果 BasePart.Touched 被沙盒容器外的實例通過觸摸標示,事件仍然會收到,但參數是 nil

避免設定此功能;沙盒保證在腳本可以與體驗中的任何實例互動時,更弱。

存取服務

即使沒有 AccessOutsideWrite ,沙盒容器中的腳本仍然可以存取gameworkspace和服務。這個訪問可以讓腳本仍然能夠呼叫這些全球變量的有用方法,例如 DataModel.GetService ,但仍然需要驗證其子實例的訪問。

內部傳送案例

如果實例通過不經過 Roblox API 的函數呼叫傳送,引用將被保留。然而,如果以這種方式傳送 ModuleScript,它不能沒有 AccessOutsideWrite 被要求。這是因為 ModuleScript 的返回通常是可變更的,並且可以由沙盒中的腳本修改。

腳本功能控制

這組功能控制一些腳本的一般方面:

請記住,預設功能限制仍然適用。即使 LoadString 已啟用,體驗仍然必須在 ServerScriptService 中啟用它,並且仍然只適用於服務伺服器。

要創建新實例,除了 創建實例 外,還需要額外的引擎 API 功能提供該實例的訪問。

引擎 API 存取控制

最後一組能力控制對各種引擎 API 的腳本存取:

  • 基本 - 存取簡單的實例和必要的建造方塊
  • 音訊 - 存取與音訊 API 相關的實例
  • 資料儲存 - 存取資料儲存和記憶儲存API
  • 網路 - 存取 HTTP 網路 API
  • 物理 - 存取與物理相關的實例
  • 使用者介面 - 存取與使用者介面相關的實例
  • CSG :存取與構造性固體幾何(CSG)相關的實例和功能
  • 聊天 : 存取經驗內聊天相關的實例
  • 動畫 : 存取與動畫相關的實例
  • 頭像 :存取與頭像相關的實例
  • 輸入 : 存取與使用者輸入相關的實例
  • 環境 : 存取與環境控制相關的實例
  • 遠端事件 :用於內部網路操作的實例訪問

還有一些情況,在執行指令碼之外,沒有任何功能可用。這些包括以下 HttpService 方法:

如果使用必要的能力無法存取實例屬性或方法,將會報告錯誤,描述缺少的能力。

最後,能力目前並不適用於 Roblox 引擎中的每個實例。本節或下一節未列出的實例無法從沙盒容器中與互動,並發出錯誤說明未分配的 能力 無法提供給當前腳指令碼。

額外限制是 getfenvsetfenv 功能在沙盒容器中的腳本無法使用。

僅限腳本存取實例。實例本身仍然可以存在並在沙盒容器內自行運作。燈光仍然閃亮,使用者介面仍然可見,已連接的音響設定仍然播放聲音。

引擎 API 功能分配

以下是每個引擎 API 功能的實例和方法列表 (如果與實例功能不同):

容器之間的互動

巢穴容器

當一個沙盒容器被納入另一個容器時,內部容器的實例可以存取外部容器。

內部容器的功能受外部容器的功能限制。例如,如果外部容器具有 基本音訊CSG 的功能,而內部容器具有 基本網路 ,在執行階段時只有 基本 功能可用於內部容器。

如果內部和外部容器之間沒有共用能力,結果的能力集將為空。

可綁定的功能和事件

BindableEventBindableFunction 提供與容器通訊的最佳方式或允許它運行回調功能,這些功能本身不允許直接使用。

當事件或功能被發射時,連線會在註冊它們的功能的上下文中執行。這意味著如果事件或功能回呼被沙盒容器註冊,它將使用該容器的功能來呼叫。如果回呼由外部代碼註冊,當沙盒容器腳本呼叫它們時,它們會使用你的功能的能力來執行你的功能。

要注意的是,即使在 AccessOutsideWrite 功能的情況下,沙盒中的腳本也無法在容器外呼叫容器內的事件或功能,如果它們的能力集比容器本身還大。

模組需需要 必填

內部 ModuleScripts 可以像往常一樣被沙盒容器要求。然而,如果目標實例位於容器外,則 ModuleScript 只能要求,如果可用的能力集與容器可用的能力相同或較小,否則無法要求。

此限制不適用於 RunClientScriptRunServerScript 功能。如果 ModuleScript 被放置在只包含 RunClientScript 但需要從具有 RunServerScript 功能的腳本中獲得的容器中,它可以成功並在服務伺服器上運行這些功能。

直接呼叫函數

如果在沙盒容器中需要 ModuleScript 從容器外,則一些保護功能無法使用。特別是,目標功能可以存取呼叫者可用的所有實例。如果呼叫者不在沙盒容器中,呼叫就會像是 AccessOutsideWrite 可用於它。

其他能力限制仍然適用。如果您擁有 數據儲存 存取能力,但目標模組沒有,它無法呼叫 DataStore。然而,如果你通過自己的功能與 DataStore 一起工作,目標在那次呼叫期間可以運行它。如果目標使用 task 的方法來安排線程,那些線程將失去呼叫該函數的能力。

實例可以傳送到目標模組或分配到模組欄位。

如果需要,建議使用 rawset 來指派表成員,以避免執行可能在表上設置的 __index / __newindex 超級方法。

整體建議是盡可能與 BindableEventBindableFunction 通訊。

實例移動

大多數情況下,容器之間的移動沒有限制。但是,腳本實例只能移到具有相同功能集或這些功能的子集的容器中。

這意味著沙盒容器 AccessOutsideWrite 無法只將內部的腳本重新傳回到外面並獲得更多功能。