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ソースはこちら









Qt Creator 〜起動ファイル(WindowsならEXE)を出力する〜

イントロダクション

Qtで作成されたサーバープログラム→「U16プログラミングコンテスト」で使用する、はQtで作成されていました。なのでこれをGitからPULLして起動するところまでを前回やりました。

ちなみに、Qtのインストールはこちらの本家サイトから出来ます。翻訳すれば大体わかります。

本題

Qtでの起動ができたらそのままQtから起動するのも1つの方法ですが、今回はMac用の起動ファイルを出力してみようと思っています。

動かしたらこんな感じです。

ちなみに起動ファイルの出力用コマンド(ツール)は以下の場所にある様です。

Windows

c:\Qt\QtX.X.X\msvc_20XX\bin\windeployqt.exe

Mac

~/Qt/QtX.X.X/clang_x64/bin/macdeployqt.app

自分の場合

自分はMacを使用しているのでMacでの出力を行います。なので早速ターミナルを立ち上げます。そして上記の「~/」はユーザー名のディレクトリ=ターミナルを立ち上げた時のカレントディレクトリ(現在いるフォルダ)になります。

そして下の様にコマンドを打ちます、

ユーザー名$ cd ./Qt

そしてとりあえずエンターキーを押すとディレクトリを移動しますQt直下に移動したはずです。ここで「lsコマンド」を叩きます。

ユーザー名$ ls

するとQtフォルダの中を一覧できます。場所は違うけれど下のキャプチャの様に出力されるはずです。

    この様な形でディレクトリを移動し

    ~/Qt/QtX.X.X/clang_x64/bin/macdeployqt.app

    まで移動します。 そして「lsコマンド」を叩くと上のキャプチャの様なファイルの一覧が見れるはずです。そして下の様にコマンドを叩きます。

    ls mac* 

    すると下の様なファイルがあるはずです。

    macchangeqt
    macdeployqt

このうちのmacdeployファイルを使用します。。。がQtCreatorで起動した時点でAPPファイルが作成されています。出力した場所は下に示します。

~/Qt/qt_workspace/AsahikawaProcon-Server/build-AsahikawaProcon-Server-Desktop_Qt_5_9_1_clang_64bit-Debug/AsahikawaProcon-Server.app/Contents/MacOS/AsahikawaProcon-Server

つまるところはQtクリエイターのワークスペース(ソースのあるディレクトリ)のプロジェクト名(AsahikawaProcon-Server)以下にあるというところです。

そして出力したファイルはこちらにアップしたかったのですがファイルがでかすぎでアップロードできませんでした。

自分でコンパイルして起動して見てください。ターミナルから下の様にコマンドを入力して起動できます。ちなみにQtのインストール方法などはこちらに記載しています(自分のやった時のものです)

追伸:Qtのインストールから起動までは結構苦労したのですが、失敗したこととうまくいったことを複数回に分けて記載しています、

./AsahikawaProcon-Server.app/Contents/MacOS/AsahikawaProcon-Server

ダブルクリックで起動したいところですが、今回はここまでにしておきます。

次はクライアントのプログラムを作成したいと思います。

でわでわ。。。








QtCreator 使い方〜Gitからソースを取得する〜

イントロダクション

Qtクリエイターという、開発ツールでのGitからソースをPULLしてくる手順を記載します。

Gitからクローン

QtCreatorを起動する

「新しいプロジェクト」をクリック

ここで、「プロジェクトのインポート」を選択した状態が上のキャプチャです。

そして「Gitクローン」を選択し右下の「選択」ボタンを押下します。

すると状況の様な入力部分が見れますので、ここにGitのURLとPULL(ダウンロード)先を指定します。

今回は自分がフォークしてきたU16プログラミングコンテストのサーバープログラムをPULLします。実際にPULLしたいリポジトリへ移動して右上にある下の様なボタンを押下します。

するとURLが表示されているのでそれを上のテキストボックスへペースとします。下の様な感じです。

PULL開始

PULL完了

PULLしたプロジェクトを起動

プロジェクトの設定はそのままで右下のボタンを押下

そして左下のボタンを押下

実行するとエラーが出ました。がそれを修正しました。赤字の部分を削除する修正です。

this->ui->SearchRadio->isChecked()
this->ui->SeachRadio->isChecked()

改めて起動!

警告などがありましたが動きました。

感想

やってみると、思いの外簡単にできました。これでC++とかJavaとかPythonとか。。。興味のあるプロジェクト、アプリなどをリポジトリからPULLして自分でいじったりできるのでやってよかったと思います。

でわでわ。。。