マルチプレイヤーの不正行為を防止


10

小さなインディースタイルのマルチプレイヤーゲームの開発はほぼ完了です。私は人々がシングルプレイヤーでチートすることを許可するつもりですが、これは明らかにマルチプレイヤーでは受け入れられません。平均的なジョーがチートエンジンのようなものを使用してゲームの一部を変更するのを止めるのに役立つ方法を知っている人はいますか?私は現在、クライアントがゲームで使用する各設定ファイル(XMLとして保存)のMD5ハッシュを数秒ごとに検証のためにゲームサーバーにアップロードすることを計画していますが、メモリエディターなどを停止するためにできることはありますか? ?


2
この記事をお勧めします
。BuildMultiplayer

回答:


8

ローカルで変更されたコードが心配な場合は、誰かが通知コードを変更してMD5ハッシュの静的リストを送信していないことを確認するにはどうすればよいでしょうか?実際、これを行うためにコードを変更する必要すらありません。かなり基本的なプロキシが必要です(SSLがないと仮定しますが、それでも少しの努力で偽造される可能性があります)。

あなたが望むことをする唯一の方法は、サーバーを持ち、クライアントをまったく信用しないことです。すべての計算はサーバーで処理する必要があり、すべてのアクションは少なくともある程度可能であることが確認されています。たとえば、クライアントが少し前に反対側にいたことがわかっているときに、マップの一方の側に移動したいと言ってはいけません。ゲームに不可欠です真ん中やってすべてでサーバがなければ、それは不可能、なぜなら誰かスマート意志を浮気していないし、常にクライアントに組み込むことができるあらゆるものを回避する方法を見つけます。たとえ1つでも、状況を少し操作するためのさまざまな方法をすべて考えなければ、まだ可能です。たとえば、前に述べた移動の検証:単純なポイントツーポイント計算を行うと、壁を介してテレポートできる可能性があります。

では、問題は、「平均的なジョー」はどの程度平均的かということです。コード編集とメモリエディタについてはすでに説明しました。それは私が個人的に平均レベルを検討するものを上回っています。そのレベルについて心配したい場合は、すべての重い作業を行う別の信頼されたサーバーが必要であり、クライアントは本質的に表示デバイスと入力デバイスに限定されます。


2
@ user185812:通常、承認された回答をマークする前に少なくとも数時間待つことをお勧めします。個人的には私の回答はかなり素晴らしいと思いますが(私は偏見があります)、他の回答はおそらくより多くの入力を持っているでしょう。
Matthew Scharley、2012

@MatthewScharley-心配ありません。;)
Martin Sojka、2012

11

クライアントは敵の手中にあります。(オンラインワールドデザインの法則

実際、ほとんどのチートを打ち負かす唯一の方法は、クライアントを「シンクライアント」にすることです。つまり、入力および出力デバイスとしてのみ機能し、正確に必要以上の情報を提供しないことです。

これは自動化を停止せず、受動的な情報収集と分析を停止しませんが、これらが大きな影響を与えないようにゲームを設計できます。

これにより、サーバーが信頼する不正な形式のメッセージを介して他のユーザーがハッキングするのを防ぐことはできません。SQLインジェクション攻撃からWebサイトを保護するのと同じように、クライアントはサーバーからのメッセージを保護する必要があります。

シングルプレイヤーゲームにも同じクライアントを使用したいので、解決策はローカルサーバーを別のプロセス/スレッドで実行し、内部的にクライアント/サーバー設定として扱うことです。「チート」はサーバー側で機能します。Minecraftも同様のことを行いますが、ゲームエンジンをそのような方法でインターフェイスから分割した最初のゲームではありません。

推奨読書:


2

基本的なマルチプレーヤーゲームでは、チートエンジンのようなチートは機能しません。クライアントは、データとそれが行うように設計したアクションのみを送信しています。通常、それは、プレーヤーが「行った」ことよりも多くありません。たとえば、彼が撃っている場合、彼が走っている方向などです。したがって、彼がメモリに対して行った変更は、自分のゲームにのみ影響しますが、他のプレーヤーには変更がない、いわゆる非同期が表示されます。ほとんどのゲームはそのような非同期を検出し、非同期プレーヤーをゲームから削除します。

現在、他の不正行為の方法もありますが、それらはすべてゲームの設計方法に関するものです。

ネットワークメッセージを偽造する最も簡単なハッキングから保護するために、サーバーはこれらのパッケージの健全性をチェックする必要があります。「あの男はたった5つの画面をジャンプしただけなんだ。それは不可能だ、パッケージを否定する」(完全に同期されたルートに移動することもできます-つまり、すべてが同期され、「プレーヤーが押したボタン」だけです。一種のメッセージが送信されます-これにより、偽のネットワークメッセージは設計上役に立たなくなります。)

マルチプレーヤーでの不正行為の最後の方法は可視性ハックです。これはクライアントがクライアントに知らないプレーヤーにデータを表示するように変更することです。これの例は、戦争の霧を示していない、壁を通して見ることができる、ミニマップまたは他のものを表示している。これらを防ぐことは不可能です。


私は可視性のハックに同意しません。キャラクターが気づくまでクライアントに情報を提供しないことで、これらを防ぐことはできませんか?誤解しないでください、これは良いデザインではないかもしれません。しかし、それは防止することが不可能であることとは異なります。
xuincherguixe 2012

@xuincherguixe状況によっては不可能だと思います。たとえば、両方のクライアントが同じIPと同じポートでプレイしています。そのような場合、クライアントが他のデータ用のデータを読み取れないようにするのは、クライアントの善意だけです。
Wodzu 2013年

1

変数の値を操作する基本的なチートエンジンハックを防ぐには、それらの値を非表示にする必要があります。通常、チートエンジンは、変数の既知の値を検索し、より多くのゲームをプレイして値を変化させることにより、興味深い変数(たとえば、アビリティのゴールドやライフ、アップグレードレベルなど)のメモリロケーションを特定するために使用されます。変更すると、Cheat Engineは以前の新しい値の検索結果から新しい検索を実行します。これにより、不正行為者は値のメモリ位置を拡大でき、チートエンジンを使用してそのメモリ位置の値を変更できます。

たとえば、245 GOLDがあります。チートエンジンを使用して、245を検索し、多くのメモリロケーションを見つけます。次に、さらにプレイしてゴールドを314まで上げます。次に、以前の検索出力で値314を検索し、GOLDが格納されているメモリの場所を簡単に見つけます。

これを防ぐ方法は、実際の値をメモリの場所に保存しないことです。たとえば、必要なときにオンデマンドで実際の値を計算する必要があるオブジェクトに値を格納します。プレーヤーが245ゴールドを持っているとしましょう。値245のメモリロケーションを検索すると、多くの値が見つかるかもしれませんが、ゴールドの値が実際に格納されているメモリロケーションにはなりません。これは、ゴールドの値245を格納しないためです。ゲームが金の量を知る必要がある場合、それはその値を保持するオブジェクトに尋ね、要求に応じてそれを計算します。

したがって、ここでの質問は次のとおりです。値を明らかにしない方法でどのように正確に値を格納しますか?これは少しトリッキーで醜いものになり、それを行う方法はたくさんあると私は確信しています。私がしたいことは、ブール配列(またはバイト配列)を格納することです。配列の長さは何でもかまいませんが、13だとしましょう。その場合、実際の値に13が入る回数を表すカウンターがあります。したがって、245を表す場合、カウンターの値は18になります。これで、配列はすべてのブール値を245/13の残りに対してtrueに設定します。基本的には係数です。この場合は11なので、配列の最初の11のブール値はtrueに設定され、残りはfalseに設定されます。値を取得するために必要なことは、カウンターに配列の長さを乗算してから、真に設定されたブール値ごとに1を追加することです(最初の偽で停止)。これで、245はどこにも保存されず、金の量を変更するために操作する必要があるメモリの場所を見つけるのが難しくなります。このオブジェクトが作成されるときに、配列の長さを異なるサイズに設定することもできます(おそらく、妥当な範囲内の数値をランダムに選択します)。

編集:これはマルチプレイヤーとシングルプレイヤーに役立ちます。パケットの値が変更される可能性があるマルチプレーヤーでも実行できる不正行為があります。これには、各パケットに署名するなど、防止するためのさまざまな手法が必要になります。


1
通常、不正行為を防止するために、マルチプレーヤーゲームはサーバー上のすべてを計算するため、クライアントまたはサーバーに送信されるパケットの値を変更しても、実際のゲームに影響はありません。しかし、それでも、残りの回答は興味深いものです。
ヴァイランクール

@AlexandreVaillancourt良い点。サーバーのCPUがシグネチャを計算するのを悩ませているのです。2つのプレーヤー間でパケットを渡すだけでサーバーを高速に保ちたいのですが、あなたが指摘したように、詳しく見ていきます。
ホセマルティネス

入力をクライアントからサーバーに送信するだけの場合、すべてのパケットに署名する必要はありません。サーバー上で入力が意味をなさない場合、それらは単に拒否されるか、クライアントが不正行為のために追い出されます。サーバーはゲームの次の状態を計算し、新しい状態をすべてのプレーヤーに送信します。これは通常、不正行為を回避する方法です(このようなボットを取り除くことはありませんが、少なくともプレーヤーからの偶然の不正行為は避けます)。 。
ヴァイランクール

1
これを回避するには、サーバーに新しいライフを更新させ、新しいライフをクライアントに送信します。すべてがサーバー上で計算され、クライアントはすべての重要な事柄について単に「ダム端末」になります。クライアントは、プレーヤーからの入力をキャプチャする責任があります(「時間Tでx、yでクリック」、「ヒット」ボタンX(時間T))、それらをサーバーに送信し、サーバーから新しい状態を受信し(「プレーヤーは現在X、Yの位置にいます」、「プレーヤーにはライフZZZがあります」)、それをプレーヤーに表示します。
Vaillancourt

1
これにより、詐欺師(真ん中の男)は、必要なすべてをパケットで台無しにすることができます。サーバーが入力が有効であることを確認するため、サーバー上のゲームの状態は変更されません(「クライアントがクリックした過去0.03秒以内の5つの異なる場所で、これは正常ではありません。これらのクリックを拒否します」)、すべてのシミュレーション自体を実行ます。
Vaillancourt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.