ポケモンの相性が覚えられないのでダメージ倍率計算するLINE Botを作った。

表題の通り。ポケモン剣プレイしてたのですが、あまりに覚えられなさすぎてチャンピオンにボコボコにされたので作りました。

相性教えるBot

相性教えるBot

防御側のタイプを入力すると、攻撃側の相性を返却します。

本当は8世代のポケモンの名前を入力してダメージ倍率を出したかったのですが、使ってるポケモン図鑑のjsonが8世代対応してなかったので対応待ちです。
相性覚えられなさすぎてポケモンGOでロケット団のリーダーにも全然勝てなかったのですが、これでどうにかなりそうです。

以下ソースコード。Mojolicious::Liteというか、Perlが使いにくいのでPythonあたりで作ったほうが良かったかもしれないですね。
retrorocket/poke-weak: ポケモンの相性チェック用LINE Bot

使用VPSをWebARENA VPSクラウドからIndigoに変更しました。

使用しているVPSを
VPSクラウド 初期料金無料・月額360円~|VPS(仮想専用サーバー)はWebARENA
から
Indigo 初期料金無料・従量課金制|VPS(仮想専用サーバー)はWebARENA
に変更しました。

ベンチマーク比較

WebArena VPSクラウド(Indigo/SuitePro含)の料金/特徴/評判/性能 | VPS比較 2019年版 を見たのですが、掲載されているVPSクラウド2GBプランのCPUスコア(2317)が実感よりもかなり高く、疑問があったので、VPSクラウド(ゾーン1)とIndigoの2GBプランでUnixBenchを実行しました。

VPSクラウド

========================================================================
   BYTE UNIX Benchmarks (Version 5.1.3)

   System: xxxxxx: GNU/Linux
   OS: GNU/Linux -- 3.10.0-1062.4.1.el7.x86_64 -- #1 SMP Fri Oct 18 17:15:30 UTC 2019
   Machine: x86_64 (x86_64)
   Language: en_US.utf8 (charmap="UTF-8", collate="UTF-8")
   CPU 0: Intel Xeon E312xx (Sandy Bridge) (4400.0 bogomips)
          x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
   CPU 1: Intel Xeon E312xx (Sandy Bridge) (4400.0 bogomips)
          x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
   19:30:54 up 19 days,  6:37,  1 user,  load average: 0.01, 0.04, 0.05; runlevel

------------------------------------------------------------------------
Benchmark Run: 日 11月 10 2019 19:30:54 - 19:58:58
2 CPUs in system; running 1 parallel copy of tests

Dhrystone 2 using register variables       25924548.6 lps   (10.0 s, 7 samples)
Double-Precision Whetstone                     3925.3 MWIPS (9.8 s, 7 samples)
Execl Throughput                               1977.6 lps   (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks        310129.8 KBps  (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks           81236.5 KBps  (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks        983120.4 KBps  (30.0 s, 2 samples)
Pipe Throughput                              424206.6 lps   (10.0 s, 7 samples)
Pipe-based Context Switching                 120468.4 lps   (10.0 s, 7 samples)
Process Creation                               6587.9 lps   (30.0 s, 2 samples)
Shell Scripts (1 concurrent)                   4479.8 lpm   (60.0 s, 2 samples)
Shell Scripts (8 concurrent)                    904.1 lpm   (60.0 s, 2 samples)
System Call Overhead                         368301.9 lps   (10.0 s, 7 samples)

System Benchmarks Index Values               BASELINE       RESULT    INDEX
Dhrystone 2 using register variables         116700.0   25924548.6   2221.5
Double-Precision Whetstone                       55.0       3925.3    713.7
Execl Throughput                                 43.0       1977.6    459.9
File Copy 1024 bufsize 2000 maxblocks          3960.0     310129.8    783.2
File Copy 256 bufsize 500 maxblocks            1655.0      81236.5    490.9
File Copy 4096 bufsize 8000 maxblocks          5800.0     983120.4   1695.0
Pipe Throughput                               12440.0     424206.6    341.0
Pipe-based Context Switching                   4000.0     120468.4    301.2
Process Creation                                126.0       6587.9    522.9
Shell Scripts (1 concurrent)                     42.4       4479.8   1056.6
Shell Scripts (8 concurrent)                      6.0        904.1   1506.8
System Call Overhead                          15000.0     368301.9    245.5
                                                                   ========
System Benchmarks Index Score                                         681.1

------------------------------------------------------------------------
Benchmark Run: 日 11月 10 2019 19:58:58 - 20:27:41
2 CPUs in system; running 2 parallel copies of tests

Dhrystone 2 using register variables       51601555.8 lps   (10.0 s, 7 samples)
Double-Precision Whetstone                     7813.5 MWIPS (9.8 s, 7 samples)
Execl Throughput                               4113.1 lps   (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks        580218.7 KBps  (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks          152260.9 KBps  (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks       1825531.3 KBps  (30.0 s, 2 samples)
Pipe Throughput                              860609.2 lps   (10.0 s, 7 samples)
Pipe-based Context Switching                 238577.6 lps   (10.0 s, 7 samples)
Process Creation                              14930.7 lps   (30.0 s, 2 samples)
Shell Scripts (1 concurrent)                   6450.5 lpm   (60.0 s, 2 samples)
Shell Scripts (8 concurrent)                    940.4 lpm   (60.0 s, 2 samples)
System Call Overhead                         693496.6 lps   (10.0 s, 7 samples)

System Benchmarks Index Values               BASELINE       RESULT    INDEX
Dhrystone 2 using register variables         116700.0   51601555.8   4421.7
Double-Precision Whetstone                       55.0       7813.5   1420.6
Execl Throughput                                 43.0       4113.1    956.5
File Copy 1024 bufsize 2000 maxblocks          3960.0     580218.7   1465.2
File Copy 256 bufsize 500 maxblocks            1655.0     152260.9    920.0
File Copy 4096 bufsize 8000 maxblocks          5800.0    1825531.3   3147.5
Pipe Throughput                               12440.0     860609.2    691.8
Pipe-based Context Switching                   4000.0     238577.6    596.4
Process Creation                                126.0      14930.7   1185.0
Shell Scripts (1 concurrent)                     42.4       6450.5   1521.3
Shell Scripts (8 concurrent)                      6.0        940.4   1567.3
System Call Overhead                          15000.0     693496.6    462.3
                                                                   ========
System Benchmarks Index Score                                        1244.0

Indigo

========================================================================
   BYTE UNIX Benchmarks (Version 5.1.3)

   System: xxxxxx: GNU/Linux
   OS: GNU/Linux -- 3.10.0-1062.4.1.el7.x86_64 -- #1 SMP Fri Oct 18 17:15:30 UTC 2019
   Machine: x86_64 (x86_64)
   Language: en_US.utf8 (charmap="UTF-8", collate="UTF-8")
   CPU 0: Intel Xeon E312xx (Sandy Bridge) (4400.0 bogomips)
          Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
   CPU 1: Intel Xeon E312xx (Sandy Bridge) (4400.0 bogomips)
          Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
   10:56:17 up 1 min,  1 user,  load average: 0.28, 0.14, 0.05; runlevel 3

------------------------------------------------------------------------
Benchmark Run: Sun Nov 10 2019 10:56:17 - 11:24:27
2 CPUs in system; running 1 parallel copy of tests

Dhrystone 2 using register variables       31197605.1 lps   (10.0 s, 7 samples)
Double-Precision Whetstone                     4522.7 MWIPS (10.2 s, 7 samples)
Execl Throughput                               1894.8 lps   (29.6 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks        271307.0 KBps  (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks           69907.7 KBps  (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks       1063671.5 KBps  (30.0 s, 2 samples)
Pipe Throughput                              456484.5 lps   (10.0 s, 7 samples)
Pipe-based Context Switching                 135959.2 lps   (10.0 s, 7 samples)
Process Creation                               8357.8 lps   (30.0 s, 2 samples)
Shell Scripts (1 concurrent)                   4547.2 lpm   (60.0 s, 2 samples)
Shell Scripts (8 concurrent)                   1011.5 lpm   (60.0 s, 2 samples)
System Call Overhead                         434753.8 lps   (10.0 s, 7 samples)

System Benchmarks Index Values               BASELINE       RESULT    INDEX
Dhrystone 2 using register variables         116700.0   31197605.1   2673.3
Double-Precision Whetstone                       55.0       4522.7    822.3
Execl Throughput                                 43.0       1894.8    440.7
File Copy 1024 bufsize 2000 maxblocks          3960.0     271307.0    685.1
File Copy 256 bufsize 500 maxblocks            1655.0      69907.7    422.4
File Copy 4096 bufsize 8000 maxblocks          5800.0    1063671.5   1833.9
Pipe Throughput                               12440.0     456484.5    366.9
Pipe-based Context Switching                   4000.0     135959.2    339.9
Process Creation                                126.0       8357.8    663.3
Shell Scripts (1 concurrent)                     42.4       4547.2   1072.5
Shell Scripts (8 concurrent)                      6.0       1011.5   1685.8
System Call Overhead                          15000.0     434753.8    289.8
                                                                   ========
System Benchmarks Index Score                                         728.3

------------------------------------------------------------------------
Benchmark Run: Sun Nov 10 2019 11:24:27 - 11:52:30
2 CPUs in system; running 2 parallel copies of tests

Dhrystone 2 using register variables       60039821.0 lps   (10.0 s, 7 samples)
Double-Precision Whetstone                     9182.8 MWIPS (9.7 s, 7 samples)
Execl Throughput                               4603.8 lps   (29.8 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks        634465.0 KBps  (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks          165369.1 KBps  (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks       2085180.7 KBps  (30.0 s, 2 samples)
Pipe Throughput                              912044.0 lps   (10.0 s, 7 samples)
Pipe-based Context Switching                 274306.0 lps   (10.0 s, 7 samples)
Process Creation                              17890.6 lps   (30.0 s, 2 samples)
Shell Scripts (1 concurrent)                   7618.4 lpm   (60.0 s, 2 samples)
Shell Scripts (8 concurrent)                   1057.0 lpm   (60.1 s, 2 samples)
System Call Overhead                         833999.5 lps   (10.0 s, 7 samples)

System Benchmarks Index Values               BASELINE       RESULT    INDEX
Dhrystone 2 using register variables         116700.0   60039821.0   5144.8
Double-Precision Whetstone                       55.0       9182.8   1669.6
Execl Throughput                                 43.0       4603.8   1070.7
File Copy 1024 bufsize 2000 maxblocks          3960.0     634465.0   1602.2
File Copy 256 bufsize 500 maxblocks            1655.0     165369.1    999.2
File Copy 4096 bufsize 8000 maxblocks          5800.0    2085180.7   3595.1
Pipe Throughput                               12440.0     912044.0    733.2
Pipe-based Context Switching                   4000.0     274306.0    685.8
Process Creation                                126.0      17890.6   1419.9
Shell Scripts (1 concurrent)                     42.4       7618.4   1796.8
Shell Scripts (8 concurrent)                      6.0       1057.0   1761.6
System Call Overhead                          15000.0     833999.5    556.0
                                                                   ========
System Benchmarks Index Score                                        1418.7

やはりVPS比較に掲載されてるunixbenchのスコアはおかしい気がします(ゾーンごとに違うのかもしれないのですが、これほど差が出るかはわかりません)。こういうのは自分で計測したほうがよさそうですね。
VPSクラウド と Indigo のベンチマーク比較結果 - Qiita の記事のスコアは私が計った結果に近いです。ディスクI/OはVPSクラウドのほうが圧倒的に性能が良いです。というよりもIndigoがめちゃくちゃ遅いです。

どちらを選ぶべきか

DNS逆引きが任意のFQDNに設定できない時点でどちらも変わらないので、安いほうにしましたが、すでにVPSクラウドを使っている人が無理して乗り換える理由はないと思います。VPSクラウドのほうがロードバランサとかあるしディスクI/Oは速いので。
ただ、課金が従量制なのはかなり魅力的だと思います。少ししか使わない人はIndigoのほうがコスパが良いです。
ちなみにお金払っても逆引きは任意のFQDNに設定できません。詐欺でしょこんなん。
DNS(有料オプション) | Indigo | VPS(仮想専用サーバー)はWebARENA

逆引きは予め設定済みであり、お客さま独自ドメインでの設定への変更はできません。インスタンスのIPアドレスでの逆引き設定はできません。

Indigoのだめなところ

  1. ログインできない(ssh鍵認証できない)インスタンスが払い出される場合がある
    一回ログインできずにインスタンスを作り直しました(作り直したらログインできた)。いくらなんでもこれはない。

  2. ログインユーザのIDがわかりにくい
    CentOSの場合、centosが初期IDなのですが、書いてるページが見つけにくすぎる。
    インスタンスへのログイン方法 | Indigo | VPS(仮想専用サーバー)はWebARENA
    こんなんわからんわ。

  3. ブラウザコンソールがあるが、ログイン用のパスワードがわからない
    初期ユーザのログインパスワード未だにわからないんだけど、ssh死んだ時どうすればいいのこれ。

  4. コンパネの動作があやしい
    インスタンス停止したのに実は停止してなかったりあやしさがすごい。インスタンス操作用のAPIを使ったほうが確実かもしれません。
    WebARENA Indigo API

  5. サービス開始日をごまかした
    本当は2019/10/23にサービスが開始されたのですが、プレスリリースとかサービスページとかまるごと全部削除された後10/28開始だったことにされました。VPSクラウドの解約ルールが「月末7営業日前までに申請された場合、当月末日の解約となります。月末6営業日前から月末までに申請された場合、翌月末日の解約となります。」なので、「VPSクラウドの当月解約を防ぐためだったんじゃないの?」とか、「かなりやばげなバグを見つけたんじゃないの?」とか、いらん疑いをかけてしまいますね。

総評

いろいろやばそうだけどとりあえず使ってみます。

CentOS 7でfail2banが動作しない。

postfix-sasl向けにfail2banを導入していたのですが、failedは検知してくれてるのに全然Banできてなかったので原因を調べました。私の環境ではfirewalldとipsetを使ってBanしています。
/etc/fail2ban/jail.local はこんな感じ。

[DEFAULT]
bantime = -1
findtime = 600
maxretry = 5
backend = systemd
banaction = firewallcmd-ipset

[sshd]
enabled = true

[postfix-sasl]
enabled = true
logpath = /var/log/mail/maillog

[sshd-ddos]
enabled = true

/var/log/fail2ban.logには特に情報がありませんでした。
DEFAULTのbanactionにfirewallcmd-ipsetを設定しているので、firewallcmd-ipsetの動作を見直せば動くかなぁ。

/etc/fail2ban/action.d/firewallcmd-ipset.confはこんな感じ。

[Definition]

actionstart = ipset create fail2ban-<name> hash:ip timeout <bantime>
              firewall-cmd --direct --add-rule ipv4 filter <chain> 0 -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j <blocktype>

actionstop = firewall-cmd --direct --remove-rule ipv4 filter <chain> 0 -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j <blocktype>
             ipset flush fail2ban-<name>
             ipset destroy fail2ban-<name>

actionban = ipset add fail2ban-<name> <ip> timeout <bantime> -exist

actionunban = ipset del fail2ban-<name> <ip> -exist

firewall-cmd --reloadがないですね。そりゃ動かんわ。(2019/10/30追記)ドキュメント読む限り、reloadがないのが原因ではなかったのですが、じゃあなんで動かなかったのかがわからない…。(参考:Documentation - HowTo - Reload firewalld | firewalld)bantimeをデフォルト値にしても動作しませんでした。

/etc/fail2ban/action.d/firewallcmd-ipset.localで設定を上書きします。bantimeいらないなぁとか色々考えた結果以下で運用することにしました。

[Definition]
actionstart = ipset create fail2ban-<name> hash:ip
              firewall-cmd --permanent --direct --add-rule ipv4 filter <chain> 0 -m set --match-set fail2ban-<name> src -j <blocktype>
              firewall-cmd --reload

actionstop = firewall-cmd --permanent --direct --remove-rule ipv4 filter <chain> 0 -m set --match-set fail2ban-<name> src -j <blocktype>
             firewall-cmd --reload
             ipset flush fail2ban-<name>
             ipset destroy fail2ban-<name>

actionban = ipset add fail2ban-<name> <ip> -exist

[Init]
blocktype = DROP

無事Banされるようになりました。

Status for the jail: postfix-sasl
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- Journal matches:  _SYSTEMD_UNIT=postfix.service
`- Actions
   |- Currently banned: 9
   |- Total banned:     9
   `- Banned IP list:   大体中国

GitHubでアカウント名を別の名前で表示できるChrome拡張を作った。

2019/09/30 追記

コメントくださった方へ:
PRのレビュワーサジェストに対応 · retrorocket/github-name-alias-chrome-extension@68b5dec
PR内でのレビュワーのサジェストに対応しました。コードのリファクタリングが必要なのでストア登録はもう少しまってください。


タイトルつけるの難しいなこれ。仕事でGitHub.comを使うにあたって、すでにフリーアカウントを所持している人はそのアカウントで仕事をすることになるのですが、本名に1ミリもかすってないアカウントだと誰が誰だかわからないって話がありました。個人的には人の本名を覚えるよりも、本名に1ミリもかすってないアカウントのほうが覚えやすいのですが、確かにそういう意見もあるよなぁと思ったのでChrome拡張でどうにかしました。正確に言うと、すごい適当に作りすぎてコードが読めるレベルじゃないのと、GitHubのjsとか色々フックするのが難しくてまだ全然どうにかなってないけど、最低限どうにかしました。

作ったもの

retrorocket/github-name-alias-chrome-extension: GitHubで名前にエイリアスを設定するためのChrome拡張です

オプションページで設定してから動かしてください。
全然どうにかなってない箇所が多いのと、コードの可読性が最悪で一回きれいにしたいので、ストアへの公開は(今回は)見送っています。

使うとどうなるか

例えばretrorocketの本名がハム太郎だったとして、retrorocketの本名を知っている人がhamutaroでサジェストしたい場合

拡張を使う前

拡張を使う前

表示がハム太郎に置き換わった上で、hamutaroでサジェストできるようになります。

拡張を使った後

拡張を使った後

(「github」が「habutaro」で候補に出るようにしてるので、スクショには「github」も出てきてます)

うまくうごかないところ

さすがにアカウント名が表示される箇所を全部置換するのはやりたくないのでやりませんでした。(PR発行とか)SPAになってる箇所があるので、一回DOMが動的に書き換わってもcontent scriptが再度動いてくれないです。仕方ないのでbodyをクリックしたときに、アカウント名の再描画とサジェスト部分の再設定が走るようにしています。(MutationObserverでDOMの書き換えを検知する手もありますが、監視しすぎると処理が重くなるので今回は見送っています。)
あとサジェスト関連の動きがだいぶ怪しいです。ほぼ期待通り動かないので改善の余地ありです。GitHubのサジェストツールの上で拡張を動作させたかったのですが、GitHub側のjsの動作にフックできなかったので一部自分で実装しています。(GitHubのサジェストツールだと矢印キーで候補の選択ができますが、そこまで頑張れなかった。)
GitHubのようなtextareaの補完機能を実装する - カーソル位置の取得 - Qiita
自分でそれっぽいの書いてて思いましたが、GitHubのサジェストは大変に優秀ですね…。すごい…。

ためしたいところ

GitHubは候補の一覧をそれ用のAPIから取得しているので、このAPIのレスポンスボディを改変できればきれいに実装できるのですが、chrome.webRequestではレスポンスボディの改変はできないです。取得したレスポンスボディに自前の候補をくっつけられるような実装ができないかは試したいですね。

こんなんすぐ実装できるやんけと思ってたけど全然だめでした。

chrome.identity.launchWebAuthFlowでChromeの拡張からTwitterのOAuth認証・認可をする。

Chromeの拡張からTwitterを使いたかったのですが、認証・認可に使ってたライブラリが結局全部使えなくなったので、chrome.identity.launchWebAuthFlowで実装することにしました。

ソースコードが長いのと、使い回しができるのでGitHubにコミットしておきました。 options.js が本体です。
retrorocket/chrome-extension-twitter-oauth-sample: TwitterのOAuth1.0認証認可をChrome拡張から実施するサンプル
シグネチャをつくる部分はさすがにライブラリがあるので、安心と信頼の johan/oauth-js: A mirror of the svn http://oauth.googlecode.com/svn/code/javascript/ (sub-)repository. を使用しています。差し替えできる処理なので、好きなライブラリを使っても問題ないです。

chrome.identity.launchWebAuthFlowは非同期なので、呼び出し処理をpromiseとして定義しておかないとrequest tokenの取得が終わる前に勝手に呼び出されて認可に失敗します。ここはほんとに原因がわからなくて詰みかけました。
launchWebAuthFlow、仕様的にもOAuth 2.0向けのAPIなのに無理やりつかうのも微妙なので、Twitterは早くApplication-only authentication以外をOAuth 2.0に対応させてほしいです。

久々にOAuth周りのドキュメントとか仕様とかを読んだのですが、めちゃくちゃ忘れてるところが多かったので実装してよかったと思いました。
あと、Chromeの拡張にConsumer keyとsecret埋めこんだ場合、アプリのソースを覗かれるとkeyとsecretがバレますが、Callback URLの仕様が変わってホワイトリスト形式になり、詐称も難しくなったので、特に問題ないと思っています。