デバイストラストAPIは、あなたのゲームに参加する各プレイヤーのデバイスをどれだけ信頼できるかを教えてくれます。プレイヤーが参加すると、Robloxはそのデバイスが信頼できるかどうかを確認し、結果をデバイストラストレベルとして提供します。このチェックは、プレイヤーが参加した後にエクスプロイトを検出するRobloxの組み込みアンチチートの上にあるオプションの保護層です。
Robloxはデバイストラストレベルに基づいて何らかのアクションを取ることはありません。あなたがゲームにとってそれが何を意味するかを決定します。たとえば、同じ信頼レベルのプレイヤーをマッチングしたり、トレードなどの敏感な機能を信頼できるデバイスに制限したり、チェックに失敗したデバイスのプレイヤーを拒否したりできます。
デバイストラストAPIは、IntegrityService.EvaluatePlayerDeviceTrustコールバックとPlayer.DeviceTrustLevelプロパティで構成されています。スクリプトで使用を開始するには、信頼レベルを読むを参照してください。
デバイストラストは、セキュリティとチート緩和戦略の戦術を補完するものであり、置き換えるものではありません。
デバイストラストレベル
プレイヤーのデバイストラストレベルは、次のEnum.PlayerDeviceTrustLevelのいずれかの値です:
| レベル | 意味 |
|---|---|
| Pending | Robloxがまだデバイスをチェックしています。すべてのプレイヤーはこのレベルから始まります。 |
| Unknown | プレイヤーがサポートされていないプラットフォームにいるか、Roblox側でエラーが発生しました。Robloxはデバイスが信頼できるかどうかを判断できないため、信頼できるかどうかわからない可能性があります。 |
| None | デバイスがチェックに失敗したか、プレイヤーが検証できないプラットフォームにいるため、通常はチートに使用されます。このレベルのプレイヤーは、通常、別のデバイスに切り替えてより高いレベルに到達する必要がありますが、一部は現在のデバイスを修正できます。 |
| Standard | デバイスは一部のチェックに合格しましたが、すべてには合格していません。デバイスはほぼ安全であり、プレイヤーは通常、デバイスを更新または修正することでFullに到達できます。一部のデバイスはStandardを超えることができません。 |
| Full | デバイスはすべてのチェックに合格し、完全に安全です。 |
サポートされているプラットフォーム
Robloxは次のプラットフォームでデバイストラストをチェックします:
| プラットフォーム | ステータス | 報告された信頼レベル |
|---|---|---|
| Android | サポートされています | None, Standard, または Full |
| Chromebook | サポートされています | None, Standard, または Full |
| Meta Quest | サポートされています | None, Standard, または Full |
| Web browser | 検証できません | None |
| iOS | 近日公開 | Unknown |
| macOS | 近日公開 | Unknown |
| Windows | 近日公開 | Unknown |
| Xbox | 近日公開 | Unknown |
| PlayStation | 近日公開 | Unknown |
Robloxがプラットフォームをサポートするまで、そのプラットフォームのプレイヤーはUnknownを報告します。
サポートされているプラットフォームでは、デバイスが到達できる信頼レベルはハードウェアにも依存します。たとえば、すべてのAndroidデバイスがRobloxが使用するチェックをサポートしているわけではないため、一部のデバイスは改ざんされていなくてもStandardやFullに到達できません。サポートされているデバイスのリストについては、ヘルプセンターを参照してください。
仕組み
プレイヤーがあなたのゲームに参加すると、Robloxはそのデバイスからのハードウェア信号を使用して次のことを確認します:
- デバイスは物理デバイスであり、エミュレーターではありません。
- オペレーティングシステムは改ざんされていません(たとえば、デバイスがルート化されていないこと)。
- Robloxアプリは変更されていません。
これらのチェックから、Robloxはプレイヤーのデバイストラストレベルを計算します。システムの効果を維持するために、Robloxは評価する特定の信号を公開していません。
チェックはプレイヤーが参加する際にバックグラウンドで実行されるため、読み込みが遅れることはありません。プレイヤーは信頼レベルが利用可能になる前にプレイを開始できますので、信頼レベルが利用可能になるまでプレイヤーを信頼できないものとして扱ってください。詳細については、信頼レベルを読むを参照してください。
デバイストラストレベルはデバイスを説明するものであり、プレイヤーやそのアカウントを説明するものではありません。プレイヤーがチートをしているかどうかはわかりません。デバイス上でチートがどれだけ難しいかを教えてくれます。アカウントをチェックするには、Player:IsVerified()を使用してください。
正当なプレイヤーへの影響
デバイスチェックは完璧ではありません。チートをする意図がないプレイヤーでも、低い信頼レベルに達することがあります。これらのプレイヤーは2つのグループに分かれます。
デバイスを修正できるプレイヤー
一部のデバイスはチェックに合格する能力がありますが、設定されていない場合があります。たとえば、古いオペレーティングシステムを持つデバイス、ルート化されたデバイス、または変更されたバージョンのRobloxアプリを実行しているデバイスです。これらのプレイヤーは通常、デバイスを更新したり、公式のアプリストアからRobloxを再インストールしたり、デバイスを元の状態に戻すことで信頼レベルを上げることができます。影響を受けたプレイヤーには、トラブルシューティング手順をヘルプセンターで指摘できます。
デバイスを修正できないプレイヤー
他のプレイヤーは、これらのチェックが依存するハードウェアをサポートしていない古いデバイスを使用しています。これらのプレイヤーは、そのデバイスで信頼レベルを上げることができず、新しいサポートされているデバイスに切り替えることでのみ高いレベルに到達できます。詳細については、サポートされているプラットフォームを参照してください。
拒否されたプレイヤーが見るもの
あなたのゲームが信頼レベルに基づいてプレイヤーを拒否する場合、プレイヤーは切断され、メッセージが表示されます。このメッセージは自分で書くことができ、たとえばプレイヤーがまだプレイできるモードを指摘することができます。そうしない場合、Robloxはプレイヤーが参加できなかった理由とデバイスを修正する方法を説明するデフォルトメッセージを表示します。
実装
影響を見積もる
デバイストラストに基づいてアクションを起こす前に、各信頼レベルがどれだけのプレイヤーをカバーしているかを確認してください。アンチチートページでは、サポートされているプラットフォームでのデイリーアクティブユーザー、プレイ時間、収益が信頼レベルごとにどのように分かれているかを見積もります。これを表示するには、ゲームの所有者であるか、体験の分析を表示する権限を持っている必要があります。
- Creator HubのCreationsページに移動し、ゲームを選択します。
- 左側のメニューでSafetyを選択し、次にAnti-cheatを選択します。
ポリシーを選択する
あなたのポリシーは、ゲームが各デバイストラストレベルにどのように反応するかです。選択するには:
- Unknownがあなたのゲームにとって何を意味するかを決定します。 プレイヤーを信頼できるデバイスのプレイヤーのように扱うか、Noneのプレイヤーのように扱うか、またはゲームの異なる部分で異なる扱いをするかはあなた次第です。
- 各レベルにどのように反応するかを選択します。 次の反応は、最も少ないから最も破壊的なものまでの順であり、組み合わせることができます:
- 信頼レベルでプレイヤーをルーティングします。 プレイヤーを信頼レベルに合った場所やサーバーに送信します。たとえば、すべての人のためのカジュアルな場所と、信頼できるデバイスのためのランク付きの場所です。すべてのプレイヤーは引き続きあなたのゲームをプレイできます。例については、信頼レベルでプレイヤーをルーティングするを参照してください。
- 敏感な機能を制限します。 特定の機能(たとえばトレード)に対してより高い信頼レベルを要求し、他のゲームの残りの部分をすべての人にプレイさせます。例については、信頼レベルで機能を制限するを参照してください。
ジャンル別の推奨ポリシー
次の表は、Robloxの一般的なジャンルに対する開始ポリシーを提案します。あなたのゲームの動作に合わせて調整してください。
| ジャンル | Pending | Unknown | None | Standard | Full |
|---|---|---|---|---|---|
| 競技FPS | 結果が計算されるまで待つ | カジュアルのみ | カジュアルのみ | カジュアルとランク付き | カジュアルとランク付き |
| バトルグラウンドまたは格闘 | 結果が計算されるまで待つ | サーバーを分ける | サーバーを分ける | 信頼できるサーバー | 信頼できるサーバー |
| レース、リーダーボード付き | 結果が計算されるまで待つ | リーダーボードから外す | リーダーボードから外す | リーダーボードに表示 | リーダーボードに表示 |
| トレードハングアウト | 結果が計算されるまで待つ | トレード可能 | トレード不可 | トレード可能 | トレード可能 |
| アイドル、AFK、またはタイクーン | 結果が計算されるまで待つ | AFK報酬を得る | AFK報酬なし | AFK報酬を得る | AFK報酬を得る |
| ロールプレイまたはソーシャルハングアウト | 結果が計算されるまで待つ | フルアクセス | フルアクセス | フルアクセス | フルアクセス |
信頼レベルを読む
デバイストラストAPIのすべての使用は、プレイヤーの信頼レベルを含むPlayer.DeviceTrustLevelから始まります。プレイヤーがランク付きマッチに参加したりトレードを開始したりする際に、ゲームが決定を下す必要があるときにサーバーで読み取ります。
プロパティを読む際に次の点に留意してください:
- すべてのプレイヤーはPendingから始まり、信頼レベルが利用可能になるとプロパティが一度だけ変更されます。Robloxがデバイスのチェックを完了できない場合、プロパティはセッション全体でPendingのままになることがあります。常にPendingを敏感な機能に対して十分に信頼できないものとして扱ってください。
- サーバーで信頼レベルを読み取り、サーバーが各クライアントにどの機能を有効または無効にするかを伝えます。たとえば、RemoteEventをそのプレイヤーに発火させます。クライアントでプロパティを読むことは避けてください。プレイヤー自身のクライアントだけが自分の信頼レベルを読み取ることができ、他のクライアントはPendingを表示し、エクスプロイターはクライアントがそれをどのように扱うかを変更できます。
- スタジオでは、信頼レベルは常にPendingです。詳細については、ロジックをテストするを参照してください。
信頼レベルを待つ
ゲームの一部は、プレイヤーが開始する前に信頼レベルを必要とする場合があります。たとえば、信頼レベルに基づいてプレイヤーをロビーに送信するマッチメイキングなどです。その場合、Players.PlayerAddedでプレイヤーを保持し、コールバックが実行されるまで待機し、その後信頼レベルで続行できます。
このパターンは、プレイヤーを受け入れ、体験を調整するためにのみ使用してください。たとえば、ルーティングや機能の制限を行います。プレイヤーを拒否するには、IntegrityService.EvaluatePlayerDeviceTrustコールバックからRejectを返し、そのロジックをコールバック内に保持します。詳細については、参加時にプレイヤーを拒否するを参照してください。
次のスクリプトは、PlayerAddedが実行されるスレッドを保存し、coroutine.yield()でそれを一時停止し、コールバックからtask.defer()で再開します。プレイヤーが離れた場合、またはMAX_WAIT_SECONDSの後に信頼レベルが利用できない場合、スクリプトはスレッドを再開し、プレイヤーが永遠に待たないようにします:
local IntegrityService = game:GetService("IntegrityService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
-- プレイヤーの信頼レベルを待つのを止めるまでの時間
local MAX_WAIT_SECONDS = 10
-- 各プレイヤーの信頼レベルを待っているスレッド
local waitingThreads: { [Player]: thread } = {}
-- プレイヤーを待っているスレッドを再開します(存在する場合)
local function release(player: Player, trustLevel: Enum.PlayerDeviceTrustLevel?)
local thread = waitingThreads[player]
if thread then
waitingThreads[player] = nil
task.defer(thread, trustLevel)
end
end
-- プレイヤーの信頼レベルが利用可能になるまで待機します。タイムアウトした場合はPendingを返し、プレイヤーが最初に離れた場合はnilを返します。
local function waitForTrustLevel(player: Player): Enum.PlayerDeviceTrustLevel?
-- Robloxはスタジオでデバイスをチェックしないため、プレイテスト中はプレイヤーを保持しないでください
if player.DeviceTrustLevel ~= Enum.PlayerDeviceTrustLevel.Pending or RunService:IsStudio() then
return player.DeviceTrustLevel
end
waitingThreads[player] = coroutine.running()
task.delay(MAX_WAIT_SECONDS, release, player, Enum.PlayerDeviceTrustLevel.Pending)
return coroutine.yield()
end
IntegrityService.EvaluatePlayerDeviceTrust = function(player, measures)
release(player, player.DeviceTrustLevel)
return { Action = Enum.PlayerDeviceTrustDecision.Accept }
end
Players.PlayerRemoving:Connect(function(player)
release(player, nil)
end)
Players.PlayerAdded:Connect(function(player)
local trustLevel = waitForTrustLevel(player)
if trustLevel == nil then
return
end
-- プレイヤーのセッションをここで開始します。たとえば、信頼レベルに合ったロビーに送信します。Pendingは信頼できないものとして扱います。
print(player.Name, "が信頼レベル", trustLevel.Name, "で参加しました")
end)信頼レベルでプレイヤーをルーティングする
プレイヤーを拒否する代わりに、信頼レベルに合った場所に送信できます。たとえば、競技ゲームはカジュアルなスタート場所にすべての人を受け入れ、信頼レベルが要件を満たすプレイヤーだけを別のランク付きの場所に送信できます。
カジュアルな場所では、プレイヤーをランク付きの場所にテレポートする前に信頼レベルをチェックします。次のスクリプトは、プレイヤーがランク付きでプレイしたいときに、クライアントUIがRemoteEventをReplicatedStorageに発火させることを前提としています:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TeleportService = game:GetService("TeleportService")
local RANKED_PLACE_ID = 12345678901234 -- あなたのランク付き場所のIDに置き換えてください
local RANKED_TRUST_LEVELS = {
[Enum.PlayerDeviceTrustLevel.Standard] = true,
[Enum.PlayerDeviceTrustLevel.Full] = true,
}
local joinRankedEvent = ReplicatedStorage:WaitForChild("JoinRanked")
joinRankedEvent.OnServerEvent:Connect(function(player)
if not RANKED_TRUST_LEVELS[player.DeviceTrustLevel] then
-- プレイヤーに信頼できるデバイスでランク付きプレイが利用できないことを知らせます
return
end
local success, result = pcall(function()
return TeleportService:TeleportAsync(RANKED_PLACE_ID, { player })
end)
if not success then
warn("ランク付き場所へのテレポートに失敗しました:", result)
end
end)プレイヤーは友達に参加するなど、他の方法でランク付きの場所に到達できます。同じポリシーを強制するには、ランク付きの場所でIntegrityService.EvaluatePlayerDeviceTrustコールバックを割り当て、参加時にプレイヤーを拒否するで説明されているように、要件を満たさないプレイヤーを拒否します:
local IntegrityService = game:GetService("IntegrityService")
local RANKED_TRUST_LEVELS = {
[Enum.PlayerDeviceTrustLevel.Standard] = true,
[Enum.PlayerDeviceTrustLevel.Full] = true,
}
IntegrityService.EvaluatePlayerDeviceTrust = function(player, measures)
if RANKED_TRUST_LEVELS[player.DeviceTrustLevel] then
return { Action = Enum.PlayerDeviceTrustDecision.Accept }
end
return {
Action = Enum.PlayerDeviceTrustDecision.Reject,
Message = "このデバイスではランク付きプレイが利用できません。カジュアルモードはプレイできます。",
}
endプレイヤーはコールバックが実行される前にプレイを開始できますので、信頼レベルがPendingの間はプレイヤーのためにランク付きマッチを開始しないでください。プレイヤーが直接参加できる場所を制御するには、安全なテレポートを構成するを参照してください。
これらの例は、Pending、Unknown、およびNoneのプレイヤーをランク付きプレイから除外します。Unknownのプレイヤーに疑いの利益を与えることに決めた場合は、両方のテーブルにUnknownを追加してください。
信頼レベルで機能を制限する
すべての人がプレイできるようにしながら、トレードなどの敏感な機能を制限するには、プレイヤーが機能を使用しようとしたときにサーバーで信頼レベルをチェックします。次のスクリプトは、両方のプレイヤーが許可された信頼レベルを持っている場合にのみトレードを許可します。許可されたレベルをテーブルにリストすることで、ポリシーを一箇所に保持できます:
local TRADE_TRUST_LEVELS = {
[Enum.PlayerDeviceTrustLevel.Unknown] = true,
[Enum.PlayerDeviceTrustLevel.Standard] = true,
[Enum.PlayerDeviceTrustLevel.Full] = true,
}
local function canTrade(player: Player): boolean
return TRADE_TRUST_LEVELS[player.DeviceTrustLevel] == true
end
local function tradeItem(sender: Player, receiver: Player, itemId: string): boolean
if not (canTrade(sender) and canTrade(receiver)) then
return false
end
-- サーバーでアイテムを検証して転送します
return true
endこの例では、PendingおよびNoneのプレイヤーのトレードをブロックし、Unknownのプレイヤーにはトレードを許可します。Unknownのプレイヤーのトレードもブロックするには、テーブルからUnknownを削除します。
敏感なアクションの前にアカウントもチェックするには、信頼レベルとPlayer:IsVerified()を組み合わせて使用します。
参加時にプレイヤーを拒否する
プレイヤーをルーティングしたり機能を制限したりするだけでは不十分な場合、ゲームからプレイヤーを拒否することができます。ServerScriptServiceのScript内でIntegrityService.EvaluatePlayerDeviceTrustコールバックに関数を割り当てます。Robloxは、デバイストラストレベルが利用可能になるとすぐに、この関数を各プレイヤーに対して一度呼び出します。
たとえば、次のスクリプトは、チェックに失敗したデバイスのプレイヤーを拒否し、Unknownのプレイヤーを含む他のすべてのプレイヤーを受け入れます:
local IntegrityService = game:GetService("IntegrityService")
IntegrityService.EvaluatePlayerDeviceTrust = function(player, measures)
if player.DeviceTrustLevel == Enum.PlayerDeviceTrustLevel.None then
return {
Action = Enum.PlayerDeviceTrustDecision.Reject,
Message = "このゲームはあなたのデバイスを検証できません。",
}
end
return { Action = Enum.PlayerDeviceTrustDecision.Accept }
endコールバックを割り当てる際に次の点に留意してください:
- コールバックはサーバーでのみ実行されます。LocalScriptから割り当てることはできません。
- 各場所には1つのコールバックがあります。複数回割り当てると、最後の割り当てが以前のものを置き換えるため、単一のスクリプトで割り当ててください。ゲーム内の異なる場所は異なるコールバックを割り当てることができます。
- コールバックはPlayers.PlayerAddedが発火した後に実行されます。デバイスのチェックには時間がかかるため、コールバックが実行されるときには、Player.DeviceTrustLevelにはすでにプレイヤーの信頼レベルが含まれています。
- コールバックは、決定を下す前にデータを読み込むために待機することができます。コールバックが実行されている間、プレイヤーはプレイを続けます。
- コールバックは約10秒後にタイムアウトします。それ以上の時間がかかると、Robloxはプレイヤーを受け入れます。
- プレイヤーが離れたり、スクリプトがプレイヤーを削除したりした場合、信頼レベルが利用可能になる前に、Robloxはそのプレイヤーのためにコールバックを呼び出しません。
決定を返す
次のフィールドを持つテーブルを返します:
| フィールド | 型 | 説明 |
|---|---|---|
| Action | Enum.PlayerDeviceTrustDecision | 必須。Acceptはプレイヤーがゲームに留まることを許可します。Rejectはプレイヤーを切断します。 |
| Message | string | オプション。拒否されたプレイヤーが見るメッセージ。これを省略すると、Robloxはプレイヤーがデバイスを修正する方法を説明するデフォルトメッセージを表示します。これは、デバイスが失敗した対策に基づいています。Robloxはこのメッセージをフィルタリングし、フィルタリングに失敗した場合はデフォルトメッセージに置き換え、長すぎるメッセージは短縮します。 |
コードの誤りがプレイヤーをロックアウトすることがないように、Robloxは次の各ケースでプレイヤーを受け入れます:
- スクリプトがコールバックを割り当てていない。
- コールバックがnil、テーブルでない値、または有効なActionを持たないテーブルを返す。
- コールバックがエラーをスローします。Robloxは他のスクリプトエラーと同様にエラーを報告します。
個々の対策に応じて応答する
コールバックの第2引数measuresは、プレイヤーの信頼レベルを説明するブール値のテーブルです。値がfalseの場合、そのデバイスはその対策に失敗したことを意味します。デバイスが対策をサポートしていない場合、その値はtrueにデフォルト設定されるため、trueの値はデバイスが合格したことを証明するものではありません。対策に基づいてプレイヤーや機能を制限する場合は、falseかどうかだけを確認してください。
| 対策 | 合格する条件 |
|---|---|
| IsPlatformVersionSecure | オペレーティングシステムがRobloxが安全と見なす最小バージョン以上である。 |
| IsPlatformBootSecure | オペレーティングシステムが安全な状態で起動した。 |
| IsAppSecure | Robloxアプリが改ざんされていない。 |
対策を使用してポリシーを洗練させます。次のスクリプトは、Noneのプレイヤーを拒否し、オペレーティングシステムが安全な状態で起動しなかったStandardのプレイヤーも拒否し、他のすべてのプレイヤーを受け入れます:
local IntegrityService = game:GetService("IntegrityService")
IntegrityService.EvaluatePlayerDeviceTrust = function(player, measures)
local trustLevel = player.DeviceTrustLevel
local isRejected = trustLevel == Enum.PlayerDeviceTrustLevel.None
or (trustLevel == Enum.PlayerDeviceTrustLevel.Standard and not measures.IsPlatformBootSecure)
if isRejected then
return { Action = Enum.PlayerDeviceTrustDecision.Reject }
end
return { Action = Enum.PlayerDeviceTrustDecision.Accept }
endよくある間違い
デバイストラストAPIを使用する際に、次のパターンを避けてください:
- 信頼レベルを数値として比較する。 各信頼レベルにはValueがありますが、値の順序はデバイスをどれだけ信頼できるかを反映していません。UnknownはNoneの前に来るため、プレイヤーのレベルがNoneより大きいかどうかをチェックすると、Unknownのプレイヤーも除外されます。代わりに、許可するレベルをリストしてください。このページの例のように、Unknownのプレイヤーを受け入れたい場合は、明示的にUnknownを含めてください。
- Players.PlayerAddedからプレイヤーを拒否する。 PlayerAddedが発火したとき、プレイヤーの信頼レベルは通常まだ利用できないため、その時点でのチェックは信頼できるデバイスのプレイヤーを拒否する可能性があります。代わりに、信頼レベルが利用可能になるとすぐにRobloxが呼び出すIntegrityService.EvaluatePlayerDeviceTrustコールバックからRejectを返してください。マッチメイキングなどの他の理由でPlayerAddedで信頼レベルが必要な場合は、信頼レベルを待つを参照してください。
- コールバック内で遅い操作を実行する。 コールバックは待機できますが、約10秒後にタイムアウトし、その場合Robloxはプレイヤーを受け入れます。複数のデータストアの読み取りやHTTPリクエストは、この制限に達するのに十分な時間がかかる可能性があるため、コールバック内での待機操作は最小限に抑えてください。
- クライアントで信頼レベルを読む。 プレイヤー自身のクライアントは自分の信頼レベルを読み取ることができるため、LocalScriptで機能を表示するかリモートイベントを発火させるかを決定することがあります。エクスプロイターは自分のクライアントを制御し、これらのチェックを回避できます。代わりに、サーバーで信頼レベルを読み取り、クライアントにどの機能を有効にするかを伝えます。トレードボタンを隠すなどのクライアント側の変更は、サーバーがクライアントに伝える内容に基づいて行い、アクションが発生する前にサーバーで再度信頼レベルを確認してください。
- 信頼レベルの代わりに対策を使用する。 対策はデバイスで利用できないときにtrueになるため、デバイスはすべての対策に合格しても完全に信頼されているわけではありません。すべての対策に合格するデバイスをFullとして扱わないでください。まず信頼レベルをチェックし、対策は失敗したチェックを探すためにのみ使用してください。
ロジックをテストする
Robloxはスタジオでデバイスをチェックしないため、プレイテスト中はデバイストラストレベルがPendingのままで、コールバックは実行されません。スクリプトがPendingを信頼できないものとして扱うため、信頼レベルによってゲートされた機能もプレイテスト中は利用できません。
これらの機能をプレイテストし、ポリシーをテストするには、ポリシーを信頼レベルを受け取る関数に保持してください。RunService:IsStudio()がtrueを返す場合、信頼チェックをスキップし、各信頼レベルでポリシーを呼び出します。次のスクリプトは、信頼レベルで機能を制限するのトレード例に対してこれを行います:
local RunService = game:GetService("RunService")
local IS_STUDIO = RunService:IsStudio()
local TRADE_TRUST_LEVELS = {
[Enum.PlayerDeviceTrustLevel.Unknown] = true,
[Enum.PlayerDeviceTrustLevel.Standard] = true,
[Enum.PlayerDeviceTrustLevel.Full] = true,
}
local function isTradeAllowed(trustLevel: Enum.PlayerDeviceTrustLevel): boolean
return TRADE_TRUST_LEVELS[trustLevel] == true
end
-- すべてのトレードの前にサーバーでこれをチェックします
local function canTrade(player: Player): boolean
-- Robloxはスタジオでデバイスをチェックしないため、プレイテスト中はトレードを許可します
if IS_STUDIO then
return true
end
return isTradeAllowed(player.DeviceTrustLevel)
end
-- スタジオでは、各信頼レベルに対するポリシーの扱いを表示します
if IS_STUDIO then
for _, trustLevel in Enum.PlayerDeviceTrustLevel:GetEnumItems() do
print(trustLevel.Name, isTradeAllowed(trustLevel))
end
end制限事項
デバイストラストはチートのコストを上げますが、完全な解決策ではありません:
- 安全なゲームデザインの代わりにはなりません。 クライアントによって報告された位置、スコア、または通貨を信頼するなど、サーバー側の検証が弱い場合に依存するエクスプロイトは、信頼できるデバイスでも機能します。重要なアクションはサーバーで検証してください。詳細については、クライアント-サーバー境界のセキュリティを参照してください。
- チートを減少させますが、排除はしません。 チート開発者は時間とともに適応するため、デバイストラストをサーバー側の検出と並行して防御の1層として扱ってください。
- すべてのプラットフォームがサポートされているわけではありません。 詳細については、サポートされているプラットフォームを参照してください。