4

サーバーがクライアントから移動 (位置) 情報を受信するマルチプレイヤー ゲームがある場合、不正行為対策としてこの情報を確認する必要があります。

これは次のように行うことができます。

maxPlayerSpeed = 300; // = 300 pixels every 1 second
if ((1000 / (getTime() - oldTimestamp) * (newPosX - oldPosX)) > maxPlayerSpeed)
{
   disconnect(player); //this is illegal!
}

これは単純な例で、X 座標のみを考慮しています。ここでの問題は、サーバーが最後の位置情報の更新を受信するとすぐに oldTimestamp が保存されることです。これは、その時点でラグ スパイクがあった場合、古いタイムスタンプがサーバーによる新しい位置情報の更新よりもかなり遅れて受信されることを意味します。これは、時差が正確ではないことを意味します。

例:

  1. クライアントは言う:私は今5x10の位置にいます
  2. ラグ スパイク: サーバーはタイムスタンプ 500 でこのメッセージを受信します (通常は 30 前後で到着するはずです)。
  3. ....1秒の動き...
  4. クライアントは言う:私は今20x15の位置にいます
  5. ラグ スパイクなし: サーバーはタイムスタンプ 1530 でメッセージを受信します

サーバーは、これら 2 つの場所の時差が 10:30 であると認識します。ただし、実際の時差は 1,500 です。これにより、アンチチート検出が 1,030 では十分ではないと判断し、クライアントをキックする可能性があります。

可能な解決策: 送信中にクライアントにタイムスタンプを送信させて、サーバーが代わりにこれらのタイムスタンプを使用できるようにします。

問題:この解決策の問題点は、プレイヤーがクライアントを操作して不正なタイムスタンプを送信できることです。そのため、不正行為防止システムが機能しません。これは良い解決策ではありません。

単純に maxPlayerSpeed * 2 の速度を許可することもできますが (たとえば)、これにより、基本的に通常の 2 倍の速さでハックすることができます。これも良い解決策ではありません。

ですから、この「サーバーのタイムスタンプと遅延」の問題を修正して、不正行為対策を価値あるものにする方法について何か提案はありますか?

4

3 に答える 3

4

いやいやいや.. 当然のことながら、これはすべて間違っています。

救済策は、クライアントを信頼しないことです。クライアントにポジションを送信させないでください。ボタンの状態を送信させてください。ボタンの状態を、クライアントが「異議がない限り、前進します」と言う要求として表示します。クライアントが「前進中」メッセージを送信して前進できない場合、サーバーはそれを無視するか、一貫性を確保するために好きなことをすることができます。その場合、クライアントは自分自身をだますだけです。

パケット フラッディングによって可能になったスピード ハックについては、パケット カウンターを保持します。許可された設定よりも特定の時間枠内でより多くのパケットを送信するクライアントを排出します。クライアントは、ティック/フレーム/ワールド タイムステップごとに 1 つのパケットを送信する必要があります。タイムステップ全体の時間に基づいてパケットに名前を付けると便利です。その後、同じタイムステップの過剰なパケットを識別して無視できます。UDP を使用する場合、パッケージの損失を防ぐために、同じパケットを複数回送信することをお勧めします。

繰り返しますが、決してクライアントを信用してはいけません。これはいくら強調してもしすぎることはありません。

于 2009-11-02T19:37:48.760 に答える
3

フィルタリングによってラグ スパイクを滑らかにします。別の言い方をすれば、常に新しい位置を以前の位置と比較するのではなく、数回前の更新の位置と比較します。そうすれば、短期的なジッターは平均化されます。あなたの例では、サーバーはラグが急増する前の位置を見て、全体的にプレーヤーが妥当な速度で動いていることを確認できます。

プレーヤーごとに、単純に最後の X ポジションを保持するか、多数の最近のポジションといくつかの古いポジション (たとえば、2、3、5、10 秒前) を保持することができます。

通常、他のプレイヤーからのジッターを隠すために、通常の移動速度の範囲内でサーバー上で補間/補外を実行します。これをチート チェック メカニズムにも拡張するだけです。すべての正当な速度向上は、明らかな速度低下の後に発生し、補間はその種のエラーをカバーするのに役立ちます。

于 2009-11-01T13:48:38.120 に答える
2

アプローチに関する意見に関係なく、探しているのは「不正行為」と見なされる速度のしきい値です。距離と時間の増分が与えられると、チートのしきい値に基づいて「遠すぎた」かどうかを簡単に確認できます。

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 ミリ秒の「ラグ スパイク」(パケット受信の遅延)を意味し、遅延期間内に送信されたすべてのパケットが同様の量だけ遅延するか、パケットが順不同で受信されることを意味します。基礎となるネットワークは、これらの遅延を適切に処理する必要があります (遅延が大きすぎるパケットを破棄する、パケット配信を順番に強制するなど)。最終的な結果として、適切なパケット処理により、予想される問題は発生しません。さらに、クライアントから明示的な文字の位置を受信せず、代わりにサーバーがクライアントを明示的に修正し、クライアントから制御状態のみを受信するようにすることで、この問題を防ぐことができます。

于 2009-11-06T04:06:13.423 に答える