CHaserServer コード解析 ~U16-プログラミングコンテスト〜

イントロダクション

前回、Gitからソース(C++/Qt)PULLしてアプリケーションを起動しました。そして動かし、クライアントを作成して遊ぼうと思っています。クライアントはC#で作成されたものや、Pythonで作成されたものがあります。しかし

Java屋なのでJavaで。。。

クライアント・アプリを作成するのに、現状動いているものやサンプルを見ながら作成します。ちなみにどうはこちらにありました。なんか自分の起動したものとビジュアルが違う。。。

Javaのサンプルはこちらを参考にしたのですが、接続まではできても動きませんでした。さてここで問題です、サンプルが動かなかったらどうしたら良いでしょうか?

対策

Javaでのサンプルは動きませんでしたが、起動したサーバーにログが出力されていたのでそいつとC++のソース解析で問題を解決しようと思います。

なので、自分のGit hubにCHaserServerをフォークしてそいつをプルしました。

<サーバーログ>

QLayout: Attempting to add QLayout "" to ClientSettingForm "HotGroupBox", which already has a layout
QLayout: Attempting to add QLayout "" to ClientSettingForm "CoolGroupBox", which already has a layout
QPoint(9,16)
QPoint(5,10)
QObject::connect: No such slot MainWindow::positionChanged(qint64) in ../src/mainwindow.cpp:125
QObject::connect:  (receiver name: 'MainWindow')
WaitStart:
"res:"
false
QObject::connect: No such slot MainWindow::positionChanged(qint64) in ../src/mainwindow.cpp:348
QObject::connect:  (receiver name: 'MainWindow')
takuminoMacBook-Pro:apps takk$ ./AsahikawaProcon-Server
QLayout: Attempting to add QLayout "" to ClientSettingForm "HotGroupBox", which already has a layout
QLayout: Attempting to add QLayout "" to ClientSettingForm "CoolGroupBox", which already has a layout
QPoint(0,5)
QPoint(3,10)
QObject::connect: No such slot MainWindow::positionChanged(qint64) in ../src/mainwindow.cpp:125
QObject::connect:  (receiver name: 'MainWindow')
WaitStart:
"res:"
false
QObject::connect: No such slot MainWindow::positionChanged(qint64) in ../src/mainwindow.cpp:348
QObject::connect:  (receiver name: 'MainWindow')

ぱっと見「なんのことやら。。。」という感じがします。とりあえずは出力している文言をC++ソースから検索します。そしたら下の文言が見つかりました。

WaitStart:

TCPClient.cpp」ファイルの18行目に以下の様なコードがありました。

//レスポンス待ち
qDebug() << "WaitStart:";

名前から察するにデバック用コンソール出力メソッドが「gDebug()」メソッドでしょう。。。詳細は調べる気になりませんでした。そしてC++での文字連結は「<<」を使用していた様に思います。「cout >> "test"」の様な記述をした覚えがあります。

そんなわけで、ソース解析をここの行から解析を開始します。

1: if(this->client->waitForReadyRead(this->TIMEOUT)){
2:    //レスポンスあり
3: 
4:     QString response = "";
5: 
6:     //自動結合
7:     bool f = false;
8:     do{
9:         response += client->readLine();
10:    }while(*(response.end()-1) != '\n' && this->client->waitForReadyRead(this->TIMEOUT));

ざっくりしたコード読みですが、まぁクライアントからの送信してきた情報を読み込む処理でしょう。JavaのBufferedReaderと同じ様な感じです。ちなみに自分お作成したコードはwhile文で上のコードは「do while文」です。

とまぁ文字列をクライアントから受け取る様です。

細かく見ていきます。1行目このクラスのclientのwaitForReadyRead()メソッドを起動します。なのでこのメソッドを探します。

  1. 「this.->client->waitForReadyRead」と記載しているので
  2. このクラスのメンバ「client」を探します。(TCPClient.cpp)
  3. メンバの定義はヘッダファイル(*.h)に定義することが多いです。(C++はcppでもhでも定義可能)
  4. そして、ここで使用しているメソッドにカーソルを合わせてQtCreatorなので「F2」を押下すると対象の定義に飛ぶことができます。
  5. とりあえずはQTcpSocketクラスを使用している様です。

これで接続先から受信データを取得します。取得した時のコンソール出力時の画像です。

しかし、動かない

デバックしたりなんだり色々と試したが動きいません。Pythonでのクライアントアプリは起動確認済み。。。

じゃあ、何が悪いのか?

動きを見てみると、CHaserサーバーにアクセスして「ゲーム開始」ボタンを押下、ゲームの起動画面が表示されるところまでは動いています。

結局

接続に使用しているURLクラスから取得したHttpConnectionクラスの使い方を見ながらJavaを描きますか。。。

そして直しました。起動するメインメソッドはこちらのクラスProgram.csにありました。

しかしそれでも動かない

<動かない現象>

原因は「改行コードに使用するエスケープシーケンス"¥" or "\"」だと思ったのですが、違いました。

とりあえずは、メッセージを投げ続けてみようかと思います。

まとめ

上の動かない原因は、どんどん「コマンド」を送信してやらないとセッションタイムアウトになってしまう。ので動かなかったというわけでした。

つまり

  1. ChaserServerを起動(画面を開く)
  2. HOTの方を「自動くん」に設定する
  3. COOLの方を「TPCユーザー」の状態で隣のボタンを押下
  4. Java Socket通信開始!
  5. 「ゲーム開始」ボタンを押下

という流れで処理を行いました。

あとはループしてコマンドを送信し続ける様な流れですが、レスポンスにある10けたの数字がなんなのか?を解析する必要がありそうだが。。。

この続きは次回以降ということで(笑)

でわでわ。。。

結果

なんとか動きました。

Javaソースはこちら