チートにより、悪意のあるクライアントが任意のコンテキストでイベントをトリガーできるようになります。クライアント・サーバー間の通信を保護し、サーバー側の検証を実装し、FXServerセキュリティConvarを設定する方法を学びます。
アンチチートチームは常にアンチチートの改善に努めていますが、時としてすり抜けてしまうことがあります。
このガイドでは、イベントを適切にロックダウンすることで、サーバーのセキュリティを向上させるために実行できる一般的な方法をいくつか紹介します。
チートを使用すると、クライアントは任意のコンテキストでイベントをトリガーできるようになります。
ここでコンテキストと言うのは、クライアント->サーバー(TriggerServerEvent経由)、またはクライアントリソース->クライアントリソース(TriggerEvent経由)でイベントを実行できることを意味します。
Luaでイベントを処理する場合、イベントがクライアントとサーバーのどちらから呼び出されるかに基づいて、イベントを正しく登録することが非常に重要です。
よくある間違いは、クライアントから呼び出されるべきではないサーバーイベントを登録したり、あるいはその逆を行ったりすることであり、これは重大なセキュリティ脆弱性につながる可能性があります。
イベントが同じコンテキスト内(クライアント・クライアント間、またはサーバー・サーバー間)でトリガーされるように設計されている場合は、AddEventHandlerを使用します。これにより、イベントがネットワーク化されず、反対側から呼び出すことができなくなります。
AddEventHandler("eventName", function(eventParam1, eventParam2)
-- このコードは、イベントが同じコンテキスト内でトリガーされたときに実行されます。
end)クライアントからサーバー、サーバーからクライアントのように、異なるコンテキスト間でイベントをトリガーする必要がある場合は、RegisterNetEventを使用します。
RegisterNetEvent("eventName", function(eventParam1, eventParam2)
-- このコードは、イベントが異なるコンテキスト間でトリガーされたときに実行されます。
end)この例はクライアント向けであり、クライアント側の他のものと同様に、万全ではなく、チートクライアントによって操作される可能性があります。
同じコンテキストからの実行をブロックしたい場合(サーバー間ネットイベントがクライアントによってトリガーされるのを防ぐなど)は、イベントを登録し、送信元ソースを検証する必要があります。
RegisterNetEvent("eventName", function(eventParam1, eventParam2)
-- サーバーはサーバーからのイベントに対してネットID `65535`を送信します
if source ~= 65535 then return end
end)強力なアンチチートを構築した場合でも、サーバーイベントにチェックを追加することで、セキュリティが大幅に向上します。これはすべてを防ぐわけではありませんが、非常にお勧めするプラクティスです。以下にいくつかの良いヒントを紹介します。
これにより、ゲーム環境の整合性とセキュリティが保証されます。
以下のすべての例は、何らかのフレームワーク(ESX、QB-Coreなど)を想定しています。
これはイベントの間違った処理方法を示すためのものであり、絶対に行わないでください。ユーザー独自の入力から直接アイテムを追加することは常に脆弱な設計です。必ずユーザー入力を検証してください。
RegisterNetEvent("job:givePlayerItem", function(item, count)
local ply = FX.GetPlayerFromSource(source)
-- ユーザー独自の入力から直接アイテムを追加することは安全ではありません!
ply.addItem(item, count)
end)こちらは堅牢なセキュリティパターンです。サーバーがプレイヤーの状態と座標を追跡し、クライアントのトリガーだけに頼るのではなく、サーバー側のティックを使用してアクションを検証します。
-- ランダムな座標
local VALID_JOB_COORD = vector3(125.0, 111.1, 35.83)
local MAX_ITEM_COUNT = 10
-- ランダムな座標
local VALID_TURNIN_COORD = vector3(1888.0, 1254.1, 48.0)
local ITEM_NAME = 'log'
-- アクティブなジョブを持つプレイヤーのリスト
local activeJobs = {}
AddEventHandler("playerDropped", function ()
if not activeJobs[source] then return end
activeJobs[source] = nil
end)
function isPedWithinRange(ped, tgtCoords)
return #(GetEntityCoords(ped) - tgtCoords) < 15.0
end
-- ジョブのティックを処理し、サーバー側でアイテム付与数をインクリメントする
CreateThread(function()
while true do
for src, data in pairs(activeJobs) do
local ped = GetPlayerPed(src)
-- 範囲内にいない場合、アイテムを付与したくない
if isPedWithinRange(ped, VALID_JOB_COORD) then
-- アイテムを与えるが、MAX_ITEM_COUNTに制限する
data.itemCount = math.min(data.itemCount + 1, MAX_ITEM_COUNT)
end
end
-- 1秒に1回ジョブのティックを処理する
Wait(1000)
end
end)
RegisterNetEvent("job:startJob", function()
local ped = GetPlayerPed(source)
-- 15ユニット以内にいる場合、彼らはジョブを実行している
if isPedWithinRange(ped, VALID_JOB_COORD) then
activeJobs[source] = {
itemCount = 0,
}
end
end)
RegisterNetEvent("job:givePlayerItem", function()
local ply = FX.GetPlayerFromSource(source)
-- アクティブなジョブがない場合、これに到達するはずがありません!
local jobData = activeJobs[source]
if not jobData then return end
local ped = GetPlayerPed(source)
-- 納品座標の範囲内にいないため、変更を拒否します
if not isPedWithinRange(ped, VALID_TURNIN_COORD) then return end
-- 複数回トリガーできないようにアイテムデータをリセットします
activeJobs[source] = nil
-- サーバー側で検証されたアイテムをユーザーに追加します
ply.addItem(ITEM_NAME, jobData.itemCount)
end)何をしているかを正確に理解していない限り、以下の設定を変更すべきではないことに注意してください。Cfx.re / Adhesiveチームはチーターを防ぐために常に懸命に取り組んでいます。FXServer 8450ビルドバージョン以降では、これらの機能のほとんどがデフォルトで有効になっています。
これらのConvarが有効になっていると、プレイヤーは以下の理由でキックされる可能性が高くなります。 Connection to CNL timed out.
キックされたからといって、プレイヤーが自動的にグローバルバン(Global Ban)されるわけではありません。しかし、プレイヤーの信頼性を示す強力な指標となり、信頼レベルの評価に非常に役立ちます。
提供されたコードはコピー&ペーストでそのまま動作するように設計されていません。これらはサーバーで発生する可能性のあるいくつかの攻撃を防ぐためのヒントにすぎません。これには一定のプログラミング知識が必要です。さらにサポートが必要な場合は、いつでも私たちのDiscordに参加してください。