アプローチに関する意見に関係なく、探しているのは「不正行為」と見なされる速度のしきい値です。距離と時間の増分が与えられると、チートのしきい値に基づいて「遠すぎた」かどうかを簡単に確認できます。
time = thisTime - lastTime;
speed = distance / time;
If (speed > threshold) dudeIsCheating();
測定に使用する時間は、サーバーの受信パケット時間です。些細なことのように思えますが、キャラクターの動きごとに距離を計算しているため、非常にコストがかかる可能性があります。最適なルートは、サーバーが速度に基づいて位置を計算することであり、それがキャラクターの位置です。クライアントは位置または絶対速度を通信することはありません。代わりに、クライアントは「最大のパーセント」速度を送信します。
明確にするために:これは不正行為のチェックのためだけのものでした. あなたのコードは、サーバー上での遅延や長い処理が結果に影響を与える可能性があります。式は次のようになります。
maxPlayerSpeed = 300; // = 300 pixels every 1 second
if (maxPlayerSpeed <
(distanceTraveled(oldPos, newPos) / (receiveNewest() - receiveLast()))
{
disconnect(player); //this is illegal!
}
これは、プレイヤーの移動速度を最大移動速度と比較します。タイムスタンプは、データの処理時ではなく、パケットの受信時に決定されます。クライアントに送信する更新を決定するために気になる方法を使用できますが、チートを決定するために必要なしきい値方法については、上記はラグの影響を受けません.
1 秒目にパケット 1 を受信: 位置 1 の文字
100 秒目にパケット 2 を受信: 位置 3000 の文字
移動距離 = 2999
時間 = 99
率 = 30
不正行為は発生しませんでした。
101 秒目にパケット 3 を受信: 位置 3301 の文字
移動距離 = 301
時間 = 1
率 = 301
不正行為が検出されました。
「ラグ スパイク」と呼ばれるものは、パケット配信の遅延が非常に大きいことです。しかし、データが処理されたときではなく、各パケットが受信されたときに通過するので問題ありません。時間の計算をゲームのティック処理とは無関係に保つ場合 (その「ティック」中に発生したものと同じようにする必要があります) 遅延の高低は、サーバーがキャラクターの位置をどの程度確実に把握しているかにのみ影響し、補間 + 外挿を使用して解決します.
クライアントが位置の修正を受信していないところまで同期がずれていて、サーバーとの同期が大幅にずれている場合、重大なパケット損失と高い遅延が発生し、チート チェックでは説明できません。実際のネットワーク通信を処理する下位層でそれを考慮する必要があります。
どのゲーム データでも、理想的な方法は、サーバーを除くすべてのシステムが 100 ~ 200 ミリ秒遅れて実行されることです。50 ミリ秒ごとに意図した更新があるとします。クライアントは 1 番目と 2 番目を受け取ります。クライアントは、2 番目の更新を受信するまで、表示するデータを持っていません。次の 50 ミリ秒にわたって、既に発生した変更の進行が示されます (つまり、非常にわずかに遅れて再生されます)。クライアントはボタンの状態をサーバーに送信します。ローカルクライアントは、これらのボタンの押下に基づいて動きや効果なども予測しますが、「ボタンの状態」のみをサーバーに送信します (ボタンの数には限りがあるため、各状態を表すために必要なビット数には限りがあります。これにより、よりコンパクトなパケット形式が可能になります)。
サーバーは信頼できるシミュレーションであり、実際の結果を決定します。サーバーは、たとえば 50 ミリ秒ごとに更新をクライアントに送信します。サーバーは、2 つの既知のフレーム間を補間するのではなく、欠落しているデータの位置などを推定します。サーバーは、最後の実際の位置が何であったかを知っています。更新を受信すると、各クライアントに送信される次のパケットには、更新された情報が含まれます。クライアントは、その時点に到達する前にこの情報を受け取る必要があり、プレイヤーはそれが発生したときにそれに反応し、間違った位置が表示されることはないため、奇妙なジャンプは見られません。
クライアントに何らかの権限を持たせたり、クライアントを権限のあるサーバーとして機能させたりすることができます。重要なのは、クライアントへの信頼がどの程度影響するかを判断することです。
クライアントは定期的に、たとえば 50 ミリ秒ごとに更新を送信する必要があります。これは、500 ミリ秒の「ラグ スパイク」(パケット受信の遅延)を意味し、遅延期間内に送信されたすべてのパケットが同様の量だけ遅延するか、パケットが順不同で受信されることを意味します。基礎となるネットワークは、これらの遅延を適切に処理する必要があります (遅延が大きすぎるパケットを破棄する、パケット配信を順番に強制するなど)。最終的な結果として、適切なパケット処理により、予想される問題は発生しません。さらに、クライアントから明示的な文字の位置を受信せず、代わりにサーバーがクライアントを明示的に修正し、クライアントから制御状態のみを受信するようにすることで、この問題を防ぐことができます。