備忘録

弱小院生のメモ

Splatoon2のギア通知botを作り、お蔵入りさせたはなし

こんにちは。

アドベントカレンダーのために放置していたブログを引っ張り出してきました。

というわけで、この記事はこちらのアドベントカレンダーの16日目の記事になります。 adventar.org

今回アドベントカレンダー用に用意していたネタがあったのですが、 色々な手違い(担当日付を勘違いなど)により間に合いませんでした...

ということで今回は、記事化せず放置していたbotの話をします。

Splatoonbotを作りました

Splatoonと周辺ツールのはなし

f:id:reverent_f:20171216222238j:plain:w500

皆さんSplatoon2、遊んでますか?

もうすぐ発売5ヶ月になりますが、 先日の大型アップデートで新ルールのガチアサリも配信され、まだまだ盛り上がっているゲームです!買ってください!

さて、このゲームではガチマッチという所謂レート戦のモードがあるのですが、 その手のゲームでは、得てして対戦結果の統計を取って色々と(得意なステージとか)分析をしたいという欲求がつきものなんですね。

所謂e-sports系のコア層向けのゲームを展開しているBLIZZARD社なんかは、 こうした要求に合わせて戦績閲覧ができるAPIを公開していたり するのですが、 ライトゲーマーが多い任天堂さんは公開APIは準備してくれてはいません。

イカリングというフレンド交流機能をメインとしたはありましたが、戦績を確認することはできません。

f:id:reverent_f:20171216222300p:plain:w250

(引用 : イカリング / 久しぶりに見にいったらサービス終了してました...。)

WiiU用ソフトとして発売された前作では、キャプチャしたゲームの映像から画像認識で戦績を抽出するなんて荒技(IkaLog)で戦績の保存ツールを作成する方もいらっしゃいました。

www.slideshare.net

(割と単純な画像処理技術でも高い精度で認識できるようです。面白い話が多いので興味がある方は是非読んでみてください。)

さて、新作のSplatoon2になりますと、 新機種Switchのセールスポイントの1つであるスマホアプリ[Nintendo Switch Online]上のサービス、イカリング2が大幅パワーアップしました!

f:id:reverent_f:20171216223952p:plain:w400

(引用 : イカリング2 | スプラトゥーン2 | Nintendo Switch | 任天堂<)

戦績の確認に加えてゲームのチーム分けと連動した通話機能なんかも搭載されまして、 発表時かなりワクワクしたことを覚えています。

このサービスはPCなどからは閲覧できず、専用アプリ上からのみの閲覧となっています。

ところが、中間者攻撃の仕組みを使ってiksm_sessionという名前のセッションをハイジャックすれば、 PCでイカリング2の閲覧や、戦績情報などを引っ張れる!ということで、 色々なツールが誕生します。(SquidTrackssplatnet2statinkなど。)

さらには,毎回mitmproxyを使ってiksm_sessionを持ってくるのは面倒なので、 ニンテンドーアカウントのログイン情報からiksm_sessionを生成する人も現れました...

...が、さすがにラインを超えているということで、

10月頃(だったかな?)のアップデートでiksm_sessionの生成処理が変更され、 一部のアプリケーションを除き手動でのiksm_session取得が必要になりました。

参考 : SplatNet 2 Login Changes (and How to Avoid Making Nintendo Angry

ギア通知Botの作成

長くなりましたが以上が前置きになります。

私も面白半分で9月頃にこの非公式APIを使ったbotを作っていたので、その話をしようと思います。

当時は既に戦績保存ツール・統計可視化サービスなど一通り揃っていたので、 ごくごく個人的な要求を解決するためのbotを作りました。

(以下、スプラトゥーンを知らない方向けの説明は省いているので読み飛ばしてください)

f:id:reverent_f:20171216222324j:plain:w500

前作のダウニーさんに引き続いて、Splatoon2ではこのダウニー君が 広場にいるイカ達の装備しているギアの注文を請け負ってくれます。

前作ではマッチングしたプレイヤーが数戦分広場に止まってくれていたのですが、 今作ではマッチングしたプレイヤーは直近1戦分、その他はいいねをたくさんもらったプレイヤーで埋め尽くされるようになりました。

この変更によって、自分が欲しいギアを広場にいるプレイヤーから探すことが困難になりました。

f:id:reverent_f:20171216224838p:plain:w500

1戦分のプレイヤーしかいないので、よく注文を逃す

一方、イカリング2ではマッチングした相手の保持していたギアも

f:id:reverent_f:20171216222344p:plain:h300

このように表示されます。

そこで、イカリング2の非公式APIを使って、
バトル終了直後にマッチングした相手のギアを通知してくれるBotを作りました!

個人用通知bot

今回作成するbotの機能はこんな感じになります。

要件

  • 使用するのは自分だけ
  • バトル終了後、次のバトル開始までに通知を行う
  • 対戦相手のギアのうち、サブのギアパワーが全て揃っているものがあればそれを通知
  • 通知はslackに投げる
  • 非公式APIを利用するため、APIを叩く頻度を抑える(重要)

使用するのは自分だけなのですが、自慢したかったのでゲーム仲間とのSlackに通知させることにしました。

最後のAPI呼び出し回数については特に注意しなければなりません。

ポケモンGOの某サービスのように、サーバに負荷をかけて正規ユーザに迷惑をかけてしまうようなことは絶対に避けましょう!

Don’t make Nintendo angry

It’s always important to be careful when accessing someone else’s API. This is especially true when using an unofficial API where they don’t intend for anything other than their own apps to be accessing it.

引用 : SplatNet 2 Login Changes (and How to Avoid Making Nintendo Angry

構成

詳細は省きますが、今回利用するAPIには2種類のものがあります。

  1. 直近50戦の一覧API
  2. バトルの詳細API (query : バトルID)

定期的に1のAPIをチェックし、新しいバトルの情報があれば詳細をフェッチすれば良さそうです。

というわけで、botの構成はこんな感じになります。

f:id:reverent_f:20171216222403p:plain

中身は定期的にcurlするだけです。確かrubyで実装した気がします。

バトルにかかる時間が1回あたり3~5分程度なので、1分に1度呼び出すことにします。

このときのAPI呼び出し回数ですが、1時間あたり最大でも60回(新着チェック)+20(詳細チェック) = 80回なので充分通常利用の範囲内といえるでしょう!

結果

f:id:reverent_f:20171216222416p:plain:w300

こんなかんじで通知が飛んできます。 表示方法は試行錯誤の結果、各ギアをstampとして登録する形になりました。

複数人が使用できるように拡張する

当然Slack内の友人も利用したいという要望がでてきたため、botを拡張しました。

要件

  • 利用人数は身内の数人のみ
  • セッションの取り扱いは後で考える
  • 金がないので無料の構成にしたい

構成

なるべく金をかけずに構成するために、heroku + Railsでバックエンドを実装しました。

herokuを利用する際に困るのが、定期実行です。

herokuではcronが使えないうえに、heroku schedularでは毎分の定期実行は不可能です。

そこで今回はGoogle Apps Scriptのタイマー機能を使います。 (参考 : Google Apps Scriptを使って定期実行するcronを作る - SakanaTech)

f:id:reverent_f:20171216222432p:plain

通知オン/オフ

24時間毎分全員分の更新確認を行うわけにはいかないので、 通知のオンオフ機能をSlackのInteractive Message機能を使って実装します。

f:id:reverent_f:20171216222442p:plain:w300

結末

以上長くなりましたが目的のbotが作成できました!

あとは友人のiksm_sessionの自動更新処理を作るだけ...というところまで作った段階で、

iksm_sessionの生成方法が変更されてしまい、 実際に友人に使ってもらう前にこのbotはお蔵入りすることになりました。

まとめ

  • Slackのbotを作るのは初めてだったので良い経験になった
  • GAS便利
  • 非公式APIの使い方には気をつけよう