グラブルで覚える作業自動化 共闘クエスト編

# はじめに

転職しようと思って転職ドラフトに登録したけど指名0件だったのでこの記事を書きました。
アウトプット、知識の共有が主目的であり、決して、グラブルやその他オンラインゲームのバランスを破壊するために書いているのではないのでその点ご留意ください。
ゲーム開発者の方々にはマクロ対策として役立てていただければ幸いです。
またアプリケーションの性質を鑑みて、ソースコードは公開しません。概念と実装方法のみの提供となります。
採用担当の方で興味があるので見てみたい、という方がいましたらご連絡下さい。

またこの記事を書いている2019/06現在、私はグラブルをプレイしておりません。
最後にプレイしたのがちょうど1年ほど前となりますので、情報が古い部分もあるかもしれません。
現在の状況と違う点等あればご指摘下さい。

# 完成動作例

イメージが掴みやすいように動画を撮ってみました。
これは実際のループ部分のみですが、マウスが人間のように正確に動いているのがわかるかと思います。

![gbfKyoutou2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440324/1444726e-a50f-1aae-a587-d4551637dfba.gif)


# 環境準備

ブラウザは何でもいいですが、私はマルチユーザーが使いやすかったのでChromeを使っていました。
Selenium系を使う人はヘッドレスブラウザでもいけるのではないでしょうか。

実際に操作を行うツールについては以下の記事が参考になるかと思います。
[RPA九人衆による「ｱｶﾈﾁｬﾝｶﾜｲｲﾔｯﾀ」の自動化](https://qiita.com/mima_ita/items/d4655de865f30bb51c65)

画像の取得しやすさ、閾値を変えながらマッチングするかリアルタイムに確認できる便利さからSikuliXを推奨します。
ただしJythonで動いておりPythonのバージョンが2.7なのでライブラリがポン付けで動かない場合があります。
その点はご留意ください。
Python3系で同レベルのIDE開発が待たれます


# グラブルとは何か

> 『グランブルーファンタジー』（GRANBLUE FANTASY）は、Cygamesが開発し、Mobageが提供するスマートフォン向けソーシャルゲームである。公式の略称は「グラブル」、キャッチフレーズは「君と紡ぐ、空の物語」。
> https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%A9%E3%83%B3%E3%83%96%E3%83%AB%E3%83%BC%E3%83%95%E3%82%A1%E3%83%B3%E3%82%BF%E3%82%B8%E3%83%BC

大人気スマートフォン向けソーシャルゲームです。最近はVTuverの方が布教していたりでなかなか衰える所を知りません。
ニコニコ動画のゲームランキングでも頻繁に上位に来ています。
プロデューサーがユーザーとの距離が近く、ポカポカ運営な事でも有名です。

ちなみに人力以外のプレイは原則認められていないので、マクロがバレるとアカウントサスペンド、最悪アカウント停止になります。

私の場合、

1. 3時間休止
1. 6時間休止
1. 9時間休止
1. 永久BAN (謝罪メール効果あり)
1. 永久BAN (謝罪メール効果なし)

という感じで検挙されるたびに段々重くなっていき、2回目の永久BAN以降、メールを送っても塩対応しか返って来なくなりました。
あまりにひどいとサイゲームズ側からも法的措置も検討されるかと思いますので、やりすぎないように注意してください。
また検挙されるタイミングによっては1か月休止、いきなり永久BANというパターンもあるらしいので自己責任にて行ってください。
正直RPAに関してはオフラインゲームで練習した方が良いかと思います。

## グラブルどれぐらいやってたの？

3周年前のシャドバコラボ開始で1年半ほど、課金額20万程度、Rank225、十天を5だか6だか解放してました。
イベント箱は30～100箱ぐらい、古戦場は44～60箱ぐらいでした。
グリームニル琴、ブローディア斧刀は自動のみで12個ずつ取ってました。
オッケやフィンブル、各種ゼノなども98%ぐらいは自動で取って必要数そろってました。
機械の力のおかげです。
今流行の加速やvira等の悪いツールは一切使っていませんでした。
有料のBotツールも利用せず、全て内製です。

# RPAの方針

グラブルに置いて自動化したい定型作業はいっぱいあると思いますが、いくつかのパターンに分けられます。

* 随時のもの
    * [共闘クエスト（スラ爆）](#共闘クエスト（スラ爆）)
    * [イベントクエスト](#イベントクエスト)
    * [曜日クエスト](#曜日クエスト)
    * [古戦場クエスト](#古戦場クエスト)
    * [各種救援](#各種救援)
    * [戦果箱あけ](#戦果箱あけ)
    * [武器・キャラ合成](#武器・キャラ合成)
* 毎日やるもの
    * [自発島ハード、自発マグナ](#自発島ハード、自発マグナ)
    * アーカルム
    * その他HLクエスト自発

一覧をみて作業多すぎぃ！とか思いましたか？そんなことないです。
回せるように構成を考えてるうちが一番楽しいはずです。
戦闘はおまけなので次の構成を幅広げるためにおとなしく周回してください。

このうちアーカルムだけは自動化していませんでした。
技術的には可能だと思いますが、分岐を組むのと剣聖・グラゼロだけで殺せないパターンの存在が鬱陶しかったからです。
RPAにおいてはコストメリットがあるかどうかは永遠の課題ですのでよく考えてから自動化に取り組んでください。
また当然ですがHL自発もリスクが高いのでおすすめしません。

それぞれについて簡単に説明していきます。

## 共闘クエスト（スラ爆）
グラブルを始めた人がみんな躓くものです。
プレイヤーランク上げ、ルピー集め、キャラクター経験値上げ、エリクシール集めと全てがそろった総合栄養食です。
経験値とルピーだけなら金銀スライムでもいいのですが、エリクシールが有限なので共闘をやらないと何らかの方法で調達する必要が出てきます。
必要な人数は1~4人、準備はほとんどいりません

1. ロビー入室
1. 部屋作成（入室）
1. 部屋画面 
1. 戦闘画面
1. リザルト
1. 3に戻る

というような流れのクエストになっています。もしかしたら今はリザルトから同じクエストって選べたかもしれません。

当記事で解説します。

## イベントクエスト
大体がこれに当たります。

1. 召喚石選択(URL直接入力)
1. 戦闘画面
1. リザルト
1. 1に戻る

大体こんな流れになります。
ヘイローや通常イベントクエスト（Hell出現タイプ）の場合、
Hellが出たらそっちをやるのも入れましょう
また救援可能で硬いクエスト（ゼノ系とか、古戦場100Hellとか）は救援呼ぶのもいいです。

## 曜日クエスト

イベントクエストと実は同じです。
URL直接入力から行きます。

## 各種救援

1. 救援ページ(URL直接入力)
1. 救援ID入力
1. 召喚石選択
1. 戦闘画面
1. リザルト
1. 1に戻る

基本この流れなのですが、途中で死んでしまった場合などは抜けて次に行くパターンもありです。
古戦場などで蘇生コストを気にしないなら起こしてもいいです。
途中で抜ける場合はリザルトだけ連打する部分が必要になります。

## 戦果箱あけ

1. ガチャページ
1. クリスタルクリック
1. 箱リセット
1. 1に戻る

こんな感じ

## 武器・キャラ合成

戦果箱を大量に開けた後やヘイロー後などにやりたくなるかと思います。
今はなんかエンジェル武器が勝手にたまる仕組が実装された気がするので必要ないのかもしれません。

1. 荷物受け取り
1. 合成確認
1. 合成done
1. 2に戻る

荷物受け取りだけ別画面でやります。
複窓対応しているサイゲームズに感謝する場面ですね

## 自発島ハード、自発マグナ

これらはデイリー画面で一番上に出てくるので、

1. クエスト画面の該当位置クリック
1. 召喚石～リザルト
1. 1に戻る

という感じでやっていきます。
複雑なのは組みたくないので島ハード部分はトレハン9にしてグラゼロ、
マグナに関しては闇か光で1ターンで殺せるようにします。
戦力に自信がないうちは救援込みもありです。

# スラ爆を始める前に

アカウントを必要数用意してください。
メインアカウントだけで殺せるならサブ垢はなんでもいいですが、
心配であればヨダルラーハを持っているアカウントを用意しましょう。
ヨダの枚数が増えれば増えるほどパーティ編成に余裕が出ます。
サブ垢はDMMとかプラットフォームが違えば脱法とか聞きましたが真偽は分かりません。

また当然2垢より3垢、3垢より4垢の方がスタミナ効率に優れ、時間効率が劣ります。
そこらへんも加味して準備をしましょう。

# 実際にRPAしてみる

前置きでグラブルの話が長くなりましたがここからが本題です。

## 自動化するフローを考える

当たり前ですが、自動化する前に手で作業をやっているかと思います。
どのような手順になっているかを意識して見ましょう。

[RPAの方針](#RPAの方針)にも書きましたが、実際はもっと細かく考えます。
また自動化する、しないを抜きにして全体を考えます。
どこを自動化すると楽になるか、自動化すると大変なのかを見極めましょう。
共闘の場合であれば以下のような感じです。

1. ブラウザを立ち上げる
1. モバゲーにログインする
1. 1-2を4台分繰り返す
1. アカウントAで共闘クエストボタンをクリック
1. アカウントAで共闘内容を設定、部屋作成
1. アカウントBで共闘クエストボタンをクリック
1．アカウントBで部屋検索をフレンドのみに
1．アカウントBで5で作られた部屋にはいる
1. 5-6を3台分繰り返す
1. どれかのアカウントで共闘アイテム（経験値2倍、奥義ゲージ上昇など）を最大まで利用
1. アカウントAで共闘クエストを選択
1. アカウントBCDでReadyを押す
1. アカウントAでスタートを押す
1. アカウントBCDで攻撃ボタンを押す
1. アカウントAで攻撃ボタンを押す
1. アカウントABCDでリロードを押す
1. アカウントABCDでリロードを押す
1. 9に戻る

長いですね。今は確かクエスト選びなおす部分はなくなっている気がするのですが、
ループ部分だけで4アカウント3回ずつボタンを押す必要があります。

このうち1-3はブラウザを起動しっぱなしにしておけばいいので、自動化しなくてもよいかと思います。
ログインフローを作る手間などの方が大変かと思います。

また4-8に関しては1時間に1回必要になります。
これは共闘の時間制限が1時間だからです。
結構手間なので最終的には自動化した方がいいと思いますが、ここでは割愛します。
慣れたら実装してみましょう。

## 実装する

4台でいきなりやるとハードルが高いと思います。
まずは2台から始めましょう
1台だとメインアカウントの汁が減ってしまうので、ダメです。
それぞれのステップに分解して考えていきましょう。

### 画面の固定化
グラブルはナイスなレスポンシブデザインなので画面サイズが違うと当然ボタンのサイズが変わってきちゃいます。
しかし最高にクールなつくりをしているのでブラウザ起動したら下の方にひし形のボタンがあるかと思います。
これを押すことで常に一定のサイズにしてくれます。ありがたいので使いましょう。
別に適当なウィンドウサイズ調整ツールを使ったり作ったりしてもよいかと思います。

### イニシャライズ
マウスの移動速度や各Window位置の取得などをやります。
別にやらなくてもいいです。

### 共通関数

#### クリック人間化

Sikuliのデフォルトだと画像認識してクリックするとど真ん中をおします。
同じところをクリックしていると速攻で検挙されるので人間らしく動くように改造しましょう。
私は画像のX,Yを取得してランダムな場所をランダムな間隔でMouseDown、MouseUpするような関数を使ってました。
あとは普通のClick関数代わりにそれを使えば大体安全です。
クリック位置がランダムになるので画像よりはみ出ないように注意しましょう。
なんなら画像の8割サイズしかクリックしないとか、そういうのをお好みで入れてください。

#### ロギング

ログ出力も作っておいた方がなにかと楽しいです。
簡単なテキスト出力からAPIでのSlack通知までお好みのを用意しておきましょう。

#### ボスが来た

画像認証はある日突然やってきます。
繰り返すとどのタイミングで出るかわかるようになるんですが、どのタイミングで出てもいいように割り込みを作っておきましょう。
また音を出してアラートを出すのはJavaの何かを使ってた気がします。
ここらへんは作りこみの改善余地はあります。

### 共闘部屋画面

共闘アイテムを使わなければ特に考えることはないです。
順番にReadyを押して最後に部屋主のGOを押しましょう。
共闘アイテムを使う場合はタブを切り替えて使えなくなるまで連打しましょう。
奥義チャージは7個使えば問題ないのですが、めんどくさいので使えなくなるまで押しちゃいましょう。
私は数数えるようにしてましたが止まったときにめんどくさいだけなので押せなくなるまで押させた方がいいです。

### 戦闘画面

共闘に限って言えば順番に攻撃ボタンを押して奥義だけ打たせるのが早いです。
ただフルチェインしてしまうとGlobalCDとでも呼ぶべきものが発動してしまうので、次の行動を打つまでに30秒ぐらいかかるようになります。
また2チェインでも確か15秒ぐらいかかります。
各アカウントのメンバー調整、MVP・準MVP調整なども考える必要があります。
実装よりここがめんどくさいかもしれません。

### リザルト

共闘の場合はBackかReloadを押せば終わりです。ブックマークのボタンを押してURL直接飛ぶのもいいです。
押すタイミングで変な所に行ったりするのでよく練習してください。
リロードを知る前は一々ボタン押してました。もしかしたら今は再戦ボタンみたいなのあるかもしれないですね


### ループ部分

部屋なのか、戦闘なのか、リザルトなのかを認識してループにするのがおすすめです。
こうすることで途中で予想外の画面で止まっても再実行などしなくてもよくなります。
当然そんな判定なしでシーケンシャルに入力させる方が高速に動きますが、止まる可能性も高くなってきます。


### 実際はこんな感じ
せっかくなのでバーチャルコード書きます
これだけ読むとプログラミング初めて3日目ぐらいに見えるかもしれませんが、あまり詳しく書くのも怖いので。

```Python 

windows = [region1,region2]

def randomclick(image,region)
    image.x+image.widthのランダム値決定
    image.y+image.heightのランダム値決定
    region.MouseDown(imageの中ランダム)
    ランダム秒待ち
    region.MouseUp(imageの中ランダム)

#ループ部分
while true
    if(共闘部屋なら):
        for window in windows
            randomclick(Ready画像,window)
    if(戦闘画面なら):
        for window in windows
            randomclick(攻撃,window)
    if(リザルト画面なら):
        for window in windows
            randomclick(リロードボタン)
        ログ出力

```

実際はもっと細かい条件分岐を持たせてもいいのですが、ゆっくり動かすのであればこれでも動きます。
elifでもいいのですがそこらへんは凄い好みです。


### ログの出力と実装例

これは開始ボタンを押した後スタミナ切れたときにエリクシールを飲む部分の実装例です。
また周回ログとラップタイムが下に出ていますが、起動時オプションで標準出力に出すことも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440324/7f921de4-f211-9b94-0dab-6dbb29445e7d.png)


# 次回以降の展望

次はイベクエの周回について書こうと思います。
スキルボタン、召喚ボタンについての汎用化等が必要になります。

その次あたりは救援マルチについて書きます。
これは影響が大きそうなので書く前につぶされるかもしれません、低空みたいに。

# 終わりに

正直グラブルやめてから時間が自由になって凄いQOL上がってます。
結局自動化しても毎日1時間ごとにクリックしてあげなきゃいけないし、
新しいクエストでたら構成考えたりしなきゃいけないのであんまり変わらないです。
また長時間流していると画像認証が出て放置すると検挙されるので、完全放置は難しいです。
画像認証も色々突破方法はあるのですが、手間に見合うかというと怪しいです。
そもそもその作業自体が本当に必要か、もっと軽量な作業で代替できないかよく考えてください。

あと転職のお誘いはお待ちしております。
自動化とパフォーマンスチューニングとかが好きです。
ちなみにこの記事は2時間ちょっとぐらいで書いています。初めてのアウトプットなので死ぬほどとっ散らかってて恥ずかしいですが

もしCygames様の方でこの記事があまりにもまずい、というようでしたらセーフな感じになる編集リクエストを頂けると幸いです。

## 追記

iOSでQiitaの共有ボタンからコピーや共有すると https://qiita.com//xxxx ってなって404になるのですがこれどこで報告すればいいんですかね？
ここで言うのも何なのですが正しいURLでまだ飛べないです。
なんかiOSのせいなきがしますが、//で飛べる場所と飛べない場所がありますね。


余談ですが2P共闘で1時間320週、4P共闘で220週ぐらい出せてました。
人力のが早いのは間違いないです。