ASP.NET Core版 対人対戦できるぷよぷよをつくる(6)の続きです。前回はログイン機能を実装したので、今回はこれをつかって、ログインしてプレイしたユーザーの記録を残すことができるようにします。

ログイン用のページをつくる

まずログイン用のページをつくります。プロジェクトのPagesフォルダの配下であればどこでもよいのですが、名前空間とフォルダ名が一致しているとちょっと困った問題がおきます。そこでPages\Puyo-MatchフォルダのなかにLogin.cshtmlをつくります。そして以下のように記述します。

やることはログイン機能追加の準備 ASP.NET Core版 対人対戦できるぷよぷよをつくる(6)とほとんど同じです。ログインしていないときには[ログイン]のボタンが、ログインしているときは[ログアウト]のボタンが表示されます。ボタンを2つつくるのではなく、同じボタンに表示されるテキストを変えているだけです。

またここにはどのような処理をするのか書いていませんが、ログインまたはログアウトに成功したらゲーム用のページにリダイレクトさせます。失敗したときはページの遷移はせずに失敗した旨を表示させます。

Pages\Puyo-Match\Login.cshtml

LoginModelクラスの定義

次に実際の処理をするコードを書きます。

ハッシュ値を生成するクラスを定義します。

次にユーザー登録、ログイン、ログアウトの処理をするLoginModelクラスを定義します。インデントが深くなるので名前空間は省略します。

ログインユーザー名の取得

GetLoginPlayerNameメソッドはログインしている場合はユーザー名を返し、そうでない場合は空文字列を返します。

ユーザー登録されているか?

IsRegisteredメソッドはすでにユーザー登録されているかどうかを調べます。

ユーザー登録の処理

ユーザー登録するための処理を示します。

フォームに希望するユーザー名とパスワードを入力して送信したときに、すでに同じユーザー名で登録されていないか、2回入力したパスワードは同じかをチェックして問題がなければユーザー登録の処理をおこないます。

‘や”やタブ文字があると不具合を起こすので、最初からこれらの文字列があると登録できないようにしています。登録された内容がサーバー上にあるファイルに保存されますが、このときユーザー名とハッシュ化されたパスワードだけでなく、登録時刻をハッシュ化した文字列と勝ち数、ゲームの総得点(登録したときはいずれも0)も文字列に変換して保存しています。

ログイン処理

ログインの処理をおこなう処理を示します。ログインに成功したらゲームのページにリダイレクトさせています。正しくないユーザー名やパスワードを入力した場合はページの遷移はおこなわずに入力内容が正しくない旨を表示します。

偽装防止策

GetPlayerTokenメソッドはユーザー名したときの時刻をハッシュ化した文字列を返します。これはページにアクセスしたときにログインされているのであれば取得されます。これがあるかどうか、これがユーザー登録しているユーザーのものと一致するかどうかでなりすましを防止しようというものです。

ゲーム用ページのcshtmlの修正

次にゲームのページのcshtmlを示します。変更点はログインボタンを追加しただけです。

ログインしている場合はユーザー名を表示させログアウト用のボタンを表示します。そうでない場合はログイン用のボタンを表示させます。またログインしている場合はハンドルネームはログインユーザー名をそのまま使うのでハンドルネーム設定用のテキストボックスを非表示にしています。

JavaScript部分の修正

JavaScript部分を修正します。エントリーボタンがクリックされたときにサーバーサイドにplayerTokenもいっしょに送信します。変更部分はここだけです。

wwwroot\puyo-match\puyo-match.js

既存のクラスの修正

ゲームのページにアクセスするとログインしているならユーザーネームがloginPlayerNameに格納されます。ただしこれだけだとクライアントサイドで書き換えることができるので、偽装防止のための文字列も同時にサーバーサイドから取得してplayerTokenに保存しておきます。ゲームを開始するときに両方がそろっていればログインユーザーであると見なすことができます。

またランキングをアップさせるために自分と自分を対戦してすぐに負けて勝ち点を増やすという不正も考えられます。そこでログインしている場合はplayerTokenに同じ文字列が格納されることを利用して自作自演を防ごうとしているのですが、これは確実な方法ではありません。ブラウザを変えれば別人として認識されるし、ログインしてエントリーしたあと、ログアウトしてエントリーすれば自分同士で対戦できてしまいます。

残念ながら自演を100%見破ることはできません。IPアドレスを使う方法もありますが、PCとスマホの両方を使われてしまえば不正はやりたい放題です。ただ高スコアを取れば賞品が出るわけでもないし、そこまでする暇な人はいるのでしょうか?

PlayerInfoクラスの修正

まずプレイヤーの情報を管理するPlayerInfoクラスを修正します。

PuyoMatchGameクラスの修正

ここで追加しているプロパティは対戦している両者がログインユーザーなのかどうかを示すものです。

PuyoMatchHubクラスの修正

PlayerInfoクラスのコンストラクタの引数が増えているのでエントリーしたときの処理が変更になります。PuyoMatchHubクラスもインデントが深くなるので名前空間 PuyoMatchは省略して書きます。

Enteryメソッドが長くなったので分けました。

エントリーしたときに誰かがすでにエントリーしていたときはそのプレイヤーとの対戦が開始されます。

エントリーしたときにエントリーしている人が誰もいないときは待機することになります。

ひとつのゲームが終了したら片方の勝ち数が3になっているか調べ、勝者がログインユーザーの場合は記録を保存します。

ランキングの表示

ランキングを表示するためにScoreクラスを定義します。

Pagesフォルダの配下にランキングを表示するためのcshtmlファイルを作成します。

ページにアクセスされたらサーバー上のファイルを読み込んでScoreオブジェクトのリストを作成します。これをつかってスコア一覧を表示させます。

Pages\Puyo-Match\ranking.cshtml