ブラウザ/ HTML5ゲーム用のチート対策Javascript


35

私はjs / html5でシングルプレーヤーアクションRPGを作成することを計画しています。不正行為を防止したいと思います。マルチプレイヤーゲームにはならないため、100%の保護は必要ありませんが、ある程度の保護が必要です。

それでは、縮小と難読化以外にどのような戦略を提案しますか?

サーバー側で簡単なチェックを行うことはありませんが、サーバー側ですべてのゲーム状態の変更を維持したまま、Diablo 3のパスに行きたくありません。

それは一種のRPGになるので、値の急激な変化をチェックする統計インスペクターを作成するというアイデアを思いつきましたが、それがどのように一貫性と信頼性があるかはわかりません。

変数と関数のスコープについてはどうですか?可能な限り小さいescopeで作業する方が安全ですが、努力する価値はありますか?

とにかく、javascriptがチェックサムのようにテキストを自己検査することはありますか?

ブラウザー固有のソリューションはありますか?初期ビルドでのみChromeでそれを制限することはありません。


データはどこに保存されますか、データはどのように保存されますか?
DogDog

Diable 3についておもしろいことですが、「Diablo 1 way」はまさにそれで、クライアントを信頼していました。あなたが若すぎてそのために何が起こったのか思い出せない場合は、Google検索をしてください!
ヴァルモンド


Apoc、今私は概念実証を持っているだけで、永続性を実装していませんが、最初のビルドおよび/またはローカルストレージにDB永続性を実装して、プレイヤーが離れたところからプレイを続けることができないようにします。はい、ヴァルドモンド私はその時ディアブロの私の分け前をしました。しかし、私は競争力のあるマルチプレイヤーゲームや完全なフラグ付きAAAを構築していません。Byte56、私はコードを盗むことを心配していません(とにかく誰がそのがらくたを望みますか?)
ビリーニンジャ

あなたが本当にハック/詐欺を心配している場合は、残念ながら、あなたは、ディアブロ3のパスを行かなければならない
Noobのゲーム開発者

回答:


46

簡単な答えは、あなたはそれができないということです。特にソースからクライアント側を実行するものはすべて、あなたの戦術を簡単に打ち負かすために修正できます。クライアント側のチェッカーを配置して突然の変更を探す場合、ユーザーはチェッカーを無効にするだけです。

幸いなことに、一般的に、シングルプレイヤーゲームではごまかしがほとんどありません。唯一の大きな例外は、Line Riderのような大規模な「youtubeハイスコア」コミュニティを持つゲームです。プレーヤーはYouTubeで互いに競います。

あなたがそれを目指している場合、または人々がゲームでチートする可能性があることを受け入れるにはあまりにも頑固である場合、またはマルチスコアの形式である自分でハイスコアを維持している場合、あなたがしなければならないことはサーバー側のすべての計算です。はい、すべてが重要です。ユーザーがチェックを無効にし、チェックがあることを確認するシステムを無効にすることができるため、計算クライアント側を繰り返してユーザーにスコアを与えてからサーバーで「検証」することさえできません。

これに対するより良い答えがあればいいのですが、ありません。

とはいえ、不正行為を少し難しくするためにできることはいくつかあります。真面目な人がそれを実行してツールキットをリリースしてチートするのを止めることはありませんが、遅くなります:

  • JSを縮小して難読化します。これにより、コードが読みにくくなります。難読化を解除して並べ替えることはできますが、正しい変数名や関数名、コメントを取得することはできません。
  • 異なる言語で値を焼き付けます。この場合、PHPまたは他のサーバー側言語を使用して静的セットアップ変数を処理できます。ジャンプ距離が常に2スペースであると想定される場合、通常はプレーヤーオブジェクトのジャンプ距離を定義します。それをPHPで処理しないでください。そうすれば、JSソースは、コード全体で数百万の場所に2が塗られてしまいます。これには、JSも高速化できるという嬉しい追加の副作用があります。
  • ある程度練習すれば、ミックスに習熟し、各プレーヤーのJSをカスタムビルドすることもできます。不正行為を防ぐもう1つの方法です。各プレーヤーのコードが何らかの形で異なる場合、ツールキットの一部になる可能性のあるチートを書くことは困難です。
  • 最後に、プレーヤーのIDに基づいてソースをチェックサムできます。IPアドレスやユーザー名を言います。JSのプレーヤー固有のバージョンが何であるかを知っているので、チェックサムを焼いて、反対側で同じであることを要求できます。クライアント側のJSのように簡単に無効にできますが、ツールキットを作成するのが少し難しくなります。

そう。ご覧のように、おそらくこのルートに行く価値はありません。それは難しい。多くの本当に馬鹿げたコーディングを行う必要があり、最終的には比較的簡単に打ち負かされます。不正行為を防ぐために、サーバー側ですべての計算を行う必要があります。または手放し、不正行為が発生することを受け入れます。


ラインライダーの例は、ユーザーが自分で描いたマップをアップロードしてスコアを計算できるようにすることで、実際にサーバーサイドで行うのは非常に簡単です。しかし、アーケードのようなゲームは、大規模な作業を行わずにサーバー側でスコアを計算することはほぼ不可能です。
orlp

@nightcrackerあなたは正しいですが、Line Riderのようなものであっても、ゲームが終わってから確認するだけで、ビデオが作成され、YouTubeがすでにだまされている場合です。ユーザーがプレイを開始するときにマップをアップロードし、簡単なパスを計算して、それを送り返す必要があります。ゲームはパスを計算できないはずです。(そのゲームではないチートプルーフの作成について話している場合、それはファンにとって明らかであるほど単純です。)
DampeS8N

14

私はすでにここでそのような質問に答えました。

サーバー側で簡単なチェックを行うことはありませんが、サーバー側ですべてのゲーム状態の変更を維持したまま、Diablo 3のパスに行きたくありません。

ここで言うことができた最悪のことです。「アンチチート」エンジンを使いたければ、それをしなければなりません。サーバー側の作業を容易にするために、クライアント側に必要なものを追加できますが、クライアントを決して信頼してはなりません。持っているすべてのロジックは、少なくともサーバー側である必要があります。必要に応じてクライアント側で再現できますが、クライアント側のみのソリューションでは再現できません。

ところで、プログラムの弱点を見つけたい場合は、難読化せずに、他の人にコードを見せて、「ここに問題がある」と伝えてください。

それはあなたにとっても、コードにとっても、ユーザーにとっても、コミュニティにとっても良いことです。


3
サーバー権限の+1。クライアントを信頼しようとしても機能しません...
Valmond

クライアント側で物事を再現することは危険です。それにも注意してください。すべてがクライアント側で複製される場合、ユーザーはサーバーとのチェックを切断することでごまかすことができるからです。その後、彼らはゲームをプレイし、ビデオを録画し、YouTubeのスターになることができます。これは、このゲームのシングルプレイヤーゲームにのみ適用されます。
DampeS8N

私がクライアント側について話すとき、それは「動きの計算」、「衝突」などのためです...これは、マルチプレイヤーゲームの場合でも両側で行うことができます。サーバー側の計算は常に優先順位を考慮する必要がありますが、これはサーバーの待ち時間がある場合にクライアント側にも使用できるため役立ちます。しかし、「チートをチェックする」ロジックであるすべてのものについては、すべてがサーバー側でなければならないことに同意します。
dievardump

うん、わかった。しかし、私は自分が持っている少し自由な時間に趣味としてプロジェクトをやっています。この種のサーバーチェックを行うと、プロジェクトが非常に複雑になり、実行不可能になります。まあ、私はそれを知っているプロジェクトで動き続けます、そしてそれが大きくて深刻になり始めたら、おそらくNode.jsでいくつかの深刻なサーバー側の制御を考え出すことができます。
ビリーニンジャ

これはOPのより適切な答えである
Noobのゲーム開発者

3

まず、Object.freeze関数を使用することをお勧めします(これにより、オブジェクトの修正プログラムに対する保護が有効になります)。

これは、「新しいプロパティが追加されるのを防ぎます」、「既存のプロパティが削除されるのを防ぎます」、「既存のプロパティ、またはそれらの列挙可能性、構成可能性、書き込み可能性が変更されないようにします」。内部状態の変更は、アクセサーを介して行う必要があります。次の例はchromeで動作します(firefoxでは動作するはずですが、IEについては知りません...):

var b = {}
// Fill your object with whatever you want
b.a = "ewq"
// Freeze all changes
Object.freeze(b)
// Try to put new value. This wont throw any error, put wont work either, 
// as we shall see ...
b.b = "qwe"

// Values 
console.log(b.a); // outputs "eqw"
console.log(b.b); // outputs  undefined

5
これでさえ、決定的な詐欺師を遅くするだけです。ソースを盗むことができなければ、自分のマシンでホストし、フリーズコードを削除してから、hostsファイルを使用して、ブラウザーに新しいページが古いページであると思わせ、サーバーに再接続します。
DampeS8N

@ DampeS8Nはい、あなたは正しいと思います。
able話的な

OPで述べたように、ある程度の保護が必要です。
ビリーニンジャ

これはまったく役に立ちません!ユーザーは、実行される最初のJS関数にデバッガーブレークポイントを設定Object.freeze = function(o) {};し、JSコンソールに入力するだけです。
フィリップ

2

残念ながら、ハッキング/チートを本当に心配している場合は、diablo 3のパスを選択する必要があります。そうでない場合は、基本的なチェックを行う必要があるか、行うことを強くお勧めします。

  • 小切手を購入する-何かを購入する場合、十分な金が必要です
  • sellchecks-何かを販売している場合、インベントリトレードチェックにそのアイテムが必要です-武器を販売するのと同じです
  • 装備チェック-武器を装備している場合、持っている/所有していますか?
  • ダメージチェック-何か(敵)を攻撃している場合、武器に与えることができる最大ダメージを超えてヒットすることはできません(ここで、クライアントは、以前に保持されていたはずなので、使用した武器を知ることを期待しないでください)
  • 作成チェック-何かを作成した場合、必要なすべての材料/コンポーネントがありますか?

... 等々

1ポイントはヒーローの位置です。少し心配する必要はありませんが、それを残すことはできますが、以下のような最小限のチェックでそれを行うことをお勧めします。

  • 私はplace1 @ T1にいます。place2T2にいます。place1からplace2に移動するのに必要な最短時間で、T2-T1に一致します。マップサイズに応じて、これを小さいものから大きいものへマッピングできます。NPC-ボス、NPC-敵のスポーンエリアなどの少なくとも主要なエリアのリストが必要です(必ずしも正確な場所ではありません)

これが役に立てば、難しいように聞こえますが、実際に動作するゲームを作ることを学ぶ必要があります


素晴らしい答えです!サーバーチェックを実装することがいかに難しいかを大まかに測定するためだけに、サーバーチェックを実装する方法に関する質問を書いていました。ご覧のとおり、MMOのようなバックボーンを実装するのに何十時間も無駄にしたくはありませんが、結局のところ、クライアントのリクエストパラメーターなどをオーバーライドするだけで、簡単に不正行為を行うことができます。または、単純に楽しいゲームであるはずだったものを単純にやりすぎます-よりクールな機能を提供したり、物事を洗練したりする代わりに、セキュリティに対する無駄な努力。
ビリーニンジャ

1

基本的に不可能です。不正行為を防ぐために配置したものは何でも簡単に回避できます。

問題は、ユーザーが配布するソフトウェアを使用して、メモリ内で簡単に変更できることです。

それに、もし彼らがチートしたいなら、彼らに任せましょう。彼らは自分たちでゲームを台無しにしているだけです。この状況でチートする実際の実用的な使用法はありません。あなたは自分でゲームプレイを破壊するだけです。


1

(他の回答に加えて)不正行為を防止/軽減するために講じることができる手段についてのアイデアがありました。クライアントが一度にすべてのソースコードを与えられるのではなく、クライアントがストアで新しいアイテムを購入するたびに、特定の情報を送信する必要があるように設定することができますサーバー、およびすべての情報が本来の目的と一致する場合にのみ、購入するすべての情報を受信します。そうでない場合、サーバーはIPまたは何かをブラックリストに載せます。

これを、さまざまなソースバージョンの使用についてDampes8nが言ったことと組み合わせて使用​​できます。多くの異なるバージョンを生成する方法を見つけ出すことができれば、各ユーザーは毎回まったく異なるソースバージョンを実行し、そのソースバージョンのブラックリストもチェックして、そのソースバージョンの正しいアイテム情報が二度と提供されないようにします。

これが効果的である主な理由は、ハッカーが最初にハックを正しく取得しないと、ハックを修正するのがはるかに難しくなるためです。ハックが完全に機能しないたびに、新しいソースバージョンのIPを変更し、ハックを繰り返し書きます。


私は注意します。最後にしたいことは、誤って有料の顧客をパーマバンにすることです。
ジョンマクドナルド

@JohnMcDonald本当、それ。おそらく、そのソースバージョンを強制終了するだけです。そうすれば、誤ってトラップをトリガーした場合、ブラウザーを更新するだけで、ハッカーはすべてのハックを再コーディングできます。
-AJMansfield

0

はい、完全に行うことはできません。常にサーバーをチェックしてください。ゲームに影響を与えるものはすべて、サーバーからの承認が必要です。

それは私が他の答えを繰り返す範囲です。

ただし、サーバーをチェックするだけでなく、チートを防止するためにさらに多くのことができます。さて、特別なサーバーチェックを追加する必要があるかもしれません。ただし、クライアント側のチェックは無駄ではないことに注意してください。不正行為が関与していない場合、帯域幅とサーバーの作業が節約されます。

とは言うものの:

  • 大まかなクライアントの緩和:HTTPS経由でサービスを提供し、クロスオリジンリソース共有(CORS)を使用し、同じオリジンのみを許可し、サブリソースの整合性を使用します。サービスワーカーを実装してすべての要求に適用することをお勧めします。これは、HTTPに移動するだけではゲームが機能しないことも意味します(HTTPSがなければサービスワーカーがいないため、サーバーワーカーはCORSとサーバーはCORSを想定しています。HTTPSを介してサービスを提供する場合、サーバーは他のオリジンを拒否するため機能しません。
  • スクリプトの軽減:認証を使用し、アクションを実行するにはトークンが必要です。更新サイクルごとにサーバーはクライアントに新しいトークンを提供する必要があり、トークンは何でも実行して消費されます...有効なトークンが必要な場合、トークンは常に変化するため、推測することはできません。同じトークンを2回送信するか、間違ったトークンを送信すると、サーバーは何かが起動していることを認識します。保護を強化するために、秘密鍵を使用してトークンのメッセージ認証コード(MAC)を作成し、それをcookieに追加します。Cookieを変更するとセッションが強制終了され(キーを推測する必要があります)、トークンを変更するとMACチェックが失敗します。
  • コード変更の緩和:サブリソースの整合性(最新のブラウザーでも実行時にチェックされる)を除き、変数を制限されたスコープ内に保持します(let、自己実行匿名関数、javascriptモジュールを使用)。また、DOMに依存しないでください(属性をアタッチしてDOMオブジェクトをラップし、ラッパーに追加する必要がある場合、DOMはストレージ専用ではなくIO専用です)。この方法では、コンソール上であなたがゲームロジックに到達できないはずです(ブラウザの脆弱性を悪用しない限り)。また、開発者ツールを検出するための手法の使用を検討することもできます(これらはブラウザーごとに固有であり、すべての場合に機能しないか、将来機能しなくなる可能性があります...したがって、これは軍拡競争です)。
  • 何かが起きていますか?セッションは中断しましたか?現在の試合からプレーヤーをキックし、再度ログインするように要求します。captchaを考えてみてください。これは、「珍しいことが起こっていることを知っている」(ランダムなサーバー障害ではなかった)ことユーザーに伝えるという利点もあります。ああ、これらを記録することを忘れないでください。誤った発言を防止し、サポートチケットに回答するために、それらが発生した理由を確認できる必要があります。

はい、これはすべて緩和策です。整合性をチェックせず、ローカルスコープ内の変数に到達して混乱させるカスタムブラウザーを引き続き使用できます...その後、ゲームコードは変更されたデータを正しいトークンで送信し、サーバーチェックが行われます遊びます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.