int型の配列を文字列にしてサーバに送り、MYSQLに配列をシリアライズして登録してそれをJSON配列で受け取りUE4の配列を更新する

おばけスキャン3.0ではUE4でパラメータの管理にint配列使っているんですがCLIENTでゲームが終了したらサヨもしくはレンが勝手にゲームを進めます。

そのためにプレーヤーがゲームを終了したらその状態をサーバに送らないとダメで、プレイヤーが再びゲームをはじめたらゲームの進み具合をパラメータとしてCLIENTが受け取れないといけません。

なのでサーバにログインしてUE4の配列を文字列に変更して送信し、MYSQLに登録更新して再度ログインしたらMYSQLからパラメータを受け取らないとダメです。

MYSQLのユーザのROWにはパラメータの配列を登録してログインしたらそのROWの配列を送ります。送受信共にjsonで行いますのでその方法の備忘録です。

まず、CLIENTのUE4での処理から。

ほとんど変わってないのですが今回はint配列を送りますのでそこが相違します。

配列はそのまま送れないので一旦stringに変換して更に文字列に変換してPOSTします。

配列を’|’で結合してPOSTしています。前は配列のINSERTだったのが変わってます。今回は配列を上書きするのでINSERTでは追加になってしまうので変更しているのです。

で、受け手側のPHP

    if($_POST['appcode']==$appcode && stripos($user_agent,'Android') !== false){
        //終了コードが送られてこない場合は端末のゲームシステムに依存し、サーバの処理を終了する
        //初めてのログインならばfalseを返して端末の初期値を端末で生成し、送り、アカウントを登録してDBを生成
        //echo 'LOGIN OK : ';
        if($_POST['acount']){
            $Ghost=explode("|", $_POST['ghost']);
            try{
                //Sql connect
                $db = new PDO($host,$user,$pass);
                //view databases
                $sql = 'SHOW DATABASES';
                $results = $db->query($sql);
                //array loop
                while ($result = $results->fetch(PDO::FETCH_NUM)){
                    //Does the database exist(DBがあった場合)
                    if($result[0]==$db_name){
                        $sql = 'use '.$db_name;//DBを選択
                        if($db->query($sql)){
                            $sql = "SELECT * FROM ".$tb_name;
                            $sql=$db->query($sql);
                            //$sql is Empty
                            if(!$sql){
                            	$sql = 'INSERT INTO '.$tb_name.' (acount,password,ghost) VALUES (:acount,:password,:ghost)';
                                $sql = $db->prepare($sql);
                                $param = array(':acount'=>$_POST['acount'],':password'=>$_POST['password'],':ghost'=>serialize($Ghost));
                                $sql->execute($param);
                                echo 'アカウントを作成しました';
                            }
                            //rowを$sqlから取り出して送られたacountとpasswordが照合するものがあるか調べる
                            foreach($sql as $row){
                                if($row['acount']==$_POST['acount'] && $row['password']==$_POST['password']){
                                    if($_POST['end_code']){
                                        //end_codeが送られてきた場合はステータスをUPDATEしてserverでの冒険を始める
                                        $sql = 'UPDATE '.$tb_name.' set ghost=:ghost where id=:id';
                                        $sql = $db->prepare($sql);
                                        $param = array(':ghost'=>serialize($Ghost),':id'=>$row['id']);
                                        $sql->execute($param);
                                        session_destroy();//セッションをクリアする
                                        //冒険の関数を作っていれる
                                        echo '最新の情報を更新しパーティは冒険に出ました';
                                    }else{
                                        //endでない場合で一回目ならはserverのデータをappへ送る
                                        if(!$_SESSION['count']){//countが0なら
                                            /*  配列のままだとjsonにしても配列で作成されるのでjsonで受け取れない*/
                                            //普通の配列を得連想配列に変換する
                                            $row = unserialize($row['ghost']);//Sqlのシリアライズを戻す
                                            $key = array_keys($row);//配列のキーを取り出しておく
                                            //取り出したキーの分だけ文字列でキーをjson配列用に作り直しておく
                                            for($i=0;$i<count($key);$i++){ $keys[$i] = '"'.$i.'"'; } //配列をjson用に連想配列に作り直しておく $rows = array_combine($keys,$row); //jsonとして出力 header('Content-type: application/json'); echo json_encode($rows);//jsonをclientに出力 $_SESSION['count']++;//インクリメント //echo '本日最初のログインです更新情報を送ります'; }else{//2回目以降はDBに書き込む $sql = 'UPDATE '.$tb_name.' set ghost=:ghost where id=:id'; $sql = $db->prepare($sql);
                                            $param = array(':ghost'=>serialize($Ghost),':id'=>$row['id']);
                                            $sql->execute($param);
                                            echo $_SESSION['count'].'回目の更新です';
                                            $_SESSION['count']++;//インクリメント
                                        }
                                    }
                                    $sql = $db->prepare($sql);
                                    $exists=true;//存在している
                                    continue;//あったら終わりで次の処理へ
                                }
                            }
                            //アカウントがない場合は作成する
                            if(!$exists){
                                //testなので3項目
                                $sql = 'INSERT INTO '.$tb_name.' (acount,password,ghost) VALUES (:acount,:password,:ghost)';
                                $sql = $db->prepare($sql);
                                $param = array(':acount'=>$_POST['acount'],':password'=>$_POST['password'],':ghost'=>serialize($Ghost));
                                $sql->execute($param);
                                echo 'アカウントを作成しました';
                            }
                        }
                    }
                }
                //close mysql
                $db = null;
            }catch(PDOException $e){
                echo "DB connect failure..." . PHP_EOL;
                echo $e->getMessage();
                exit;
            }
        }

POSTされたghostは’|’で文字列から配列にデコードされています。

で、Mysqlへ接続しますがまず、テーブルが空だったらアカウントのROWを登録します。デコードされたghostの配列はsirializeされてSQLに書き込まれます。

その後、終了コードが送られてきたら情報を更新し、カウントをリセットします。

その後再びログインされたらサーバのMYSQLに保存されたパラメータをunsirializeして配列に戻し、その配列をjson用に連想配列に作り直してjsonでCLIENTに送ります。

受け取るUE4のBlueprintは次の通りです。

jsonで受け取ったデータはstring配列にキーを元にした連想配列で受け取ります。

その後TICKで更新されたstring配列から値を取り出し送信元のパラメータであるint配列に上書きしています。これで送受信とも完了です。

これを実際に動かしてみると

こんな感じで送受信できています。

送信したint配列

MYSQLにはデータベースとテーブルはあらかじめ作っておきます。

create table player_tb (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,acount varchar(12),password varchar(12),ghost varchar(1024));

こんな感じで。シリアライズする配列は大きめに作っておきます。

コメントを残す

メールアドレスが公開されることはありません。必須項目には印がついています *