# Dockerで自宅にWi-Fiコネクション代替サーバーを建てる
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">第四世代 Wi-Fiコネクション代替サーバーを提供するDockerfileと、DNSサーバーを抱き合わせたYAMLを公開しています。お手元のPCにサーバーを建てて、無改造のDSからアクセスすることができるものです。「ふしぎなおくりもの」は予め削除しているので受け取れません。 <a href="https://t.co/4y89r4qn5X">pic.twitter.com/4y89r4qn5X</a></p>— メイユール (@meilleur_pkmn) <a href="https://twitter.com/meilleur_pkmn/status/1488479167385518083?ref_src=twsrc%5Etfw">February 1, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
「ふしぎなおくりもの」を受け取れないWi-Fiコネクション代替サーバーを作りました。
ハック要素濃いめの内容なので、苦手な方はブラウザバックをお願いします。伝わる人向けに書いています。
## はじめに(ぽえむ)
> かがくの ちからって すげー!
>
> いまじゃ むせんを つかって
> せかいの ひとびとと つながるんだと
ポケモンにおいては第4・5世代にまたがるDS/Wiiの隆盛期に、「ニンテンドーWi-Fiコネクション」というインターネット通信サービスがあったことを覚えていますか。私と同年代の方々には、DS片手にマクドナルドに通った思い出のある方もいらっしゃるかと思います。
ポケモンでは「Wi-Fiひろば」「GTS」「Wi-Fiバトルルーム」「ランダムマッチ」などが提供され、先の台詞に違わない革新的な通信体験でしたが、[2014年5月20日をもって終了](https://www.nintendo.co.jp/support/information/2014/0227.html)し、3DS/Wii U向けの「ニンテンドーネットワーク」へと移行しました。
現在では、アクセスを試みても「このソフトのWi-Fiコネクションサービスは終了しました」とすげなく表示されるのみです。
---
時に、ポケモンには第3世代より「リボン」という収集要素があります。自分が好きなポケモンに可能な限りのリボンをつけて20年に渡る過去作品を一巡する「リボンコンプ」はやり込みプレイヤーの憧れの的であり、現行世代である剣盾で登場した証や二つ名を鑑みると、開発側としても世代を超えるトロフィーとして推していく意欲があることが窺えます。一説には過去作が値下がりしない原因の一つだとも...
いまや80を超えるこれらリボンのうち、ひときわ価値のあるものが第4世代、Wi-Fiバトルルームを勝ち上がることで入手する「ワールドアビリティリボン」だということは、誰もが認めるところでしょう。ポケモンバンクを通過する際に「おもいでバトルリボン」に統合されてしまいますが、全てのバトル施設リボンをコンプした場合(合計8つ)としていない場合で形が変わるという憎い仕様になっています。
前述の通りWi-Fiコネクションが終了した現在では、このリボンをゲーム内で獲得する手段はありません。

---
Wi-Fiコネクションは終了した、ゲーム内で獲得する手段がないと言いましたが、実際のところ必ずしもそうとも言えません。
ニンテンドーWi-Fiコネクションは人気なサービスであったため、世界中のハッカーがリバースエンジニアリングに[取り組みました](https://gigazine.net/news/20140523-nintendo-wii-wi-fi-connection/)し、サービス終了直後から代替サーバーが建ったと聞きます。その末裔がよく知られた「[Wiimmfi](https://wiimmfi.de/)」であり、現在では本体やソフトに改造を施さずとも接続することができると知られています。
もちろんこれに接続し、過去に挑戦した世界中の人々の記録と競い条件を満たすことによっても、データとしては相違ないワールドアビリティリボンを獲得することは可能です。しかし多くのポケモン愛好家・リボン収集勢たちはこれをよしとはしないでしょう。代表的な理由は、Wiimmfiに限らず海外の有志サーバーはどこも、現在は入手することができないはずの「ふしぎなおくりもの」を配信していることにあると見受けられます。
配布限定の貴重な道具や幻のポケモンなどが入手し放題になっていることについては目に余るものがあると思っていますし、これを擁護するつもりはありません。しかし代替サーバーの技術単体についてなら話が別です。個人的には、既にサービスが終了したゲームであり現行の作品や開発者と利益の衝突がない範囲で黙認される限りで、初代からポケットモンスターというシリーズの核である通信機能が提供されることには価値があると考えます。
だいいち私には、本質は先駆者が「手を汚して」調査開拓した内部値のエミュレーションであるところの乱数調整をはじめとして、マイコンを使用する自動化から筐体改造を伴う偽トロの取り付けまでありがたく利用してきたのに、代替サーバーだけを否定できるうまい道理もないように思われます。
ということで、「ふしぎなおくりもの」をばらまかずWi-Fiバトルルーム機能を提供してくれる、個人の倫理観的に許せる代替サーバーを作り、自分で利用しようというのが今回のテーマです。
## Wi-Fiバトルルーム
前提としてWi-Fiバトルルームを紹介し、サーバーの役割を確認します。
バトルタワーの右端がWi-Fiバトルルームの受付になっています。出場するポケモンを選択すると接続画面に遷移します。

ルームを選択します。サーバーではルーム毎に戦績を管理しており、その記録から7戦分のデータを選出し配信しています。ダウンロードが終了するとWi-Fiから切断されます。

この後の流れは通常のバトルタワーと同じです。この間には通信は行われていません。
退場後、今回の成績をサーバーに送信するかと問われます。「はい」を選択した場合には再び接続画面に遷移し、アップロードが行われます。

上記の流れの中でサーバーが果たす機能は意外にも僅かです。最低限の機能を提供することだけを考えれば、7戦分のデータ配信だけを正しく行えばWi-Fiバトルルームは成立します。リボンの付与はソフト側にもとより内蔵されている機能であり、受信したコンテンツは関与しません。
## 技術背景
今回利用するのはDockerです。可搬性に優れ破棄しやすい仮想マシンの親戚という説明でいかがでしょうか。詳しく述べるほど知りません。
全体的な構造としてはDNSサーバー(\*.nintendowifi.netがどこを指しているのかを書き換える)とWebサーバー(書き換え先で稼働しコンテンツを提供する)の合わせ技となっています。dnsmasqとApache+Monoを利用しますが、特にApacheはDSの貧相で脆弱な認証機能に対応させるためにOpenSSL共々自前でビルドする必要がありました。つまり、このサーバーはあくまで個人用であり、広くアドレスを公表するなどして公開すべきものではないことをご理解ください。
サーバー機能を提供するのは[dwc_network_server_emulator](https://github.com/barronwaffles/dwc_network_server_emulator)です。これとは断言されていませんが、前述のWiimmfiもこれに準ずるソフトウェアを利用しているものと考えられます。フォークの利用が[推奨されており](https://github.com/barronwaffles/dwc_network_server_emulator/wiki/Setting-up-a-server-from-a-fresh-installation-of-Linux)、今回構築するものもこれに従います。
ポケモンに限定して、上記サーバーの一部を置換するのが[Poké Classic Framework](https://github.com/mm201/pkmn-classic-framework)です。バトルタワーやGTSなど一部の機能に対応しています。今回対応するのは、この中でも一部のみです。バトルタワーと、GTSに預ける/引き出すくらいしか動作していません。
DSの接続にはWEPあるいはセキュリティなしのネットワークが必要です。これらの設定は問題があるとされ、現在ではデフォルトで無効化されていることのほうが多いです。必要があるのは代替サーバーだからではなく、前述の通りDS当時のハードウェアの限界による事由です。スマートフォンのテザリングなどで利用し、大切なネットワークからは切り離した状態で運用することをお勧めします。
[このページ](https://github.com/barronwaffles/dwc_network_server_emulator/wiki/Troubleshooting)下部の指示に従い、予めPCのポートを解放する必要があります。UDPはDNSサーバーが利用する53番を開けておけば、Wi-Fiバトルルームには十分です。
Windowsでしか動作確認していません。Dockerを利用するので実行時のOSは問わないと思いますが、結構PCのスペックが要求されるものと思ってください。
## 構築手順
<a href="https://github.com/mukai1011/pkmn-wfc-server"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/mukai1011/pkmn-wfc-server.png" width="460px"></a>
以下は個人的なメモだと心得てください。
1. `dnsmasq/wfc.conf` の `192.168.*.*` を自分の環境のものに変更する。
- Windowsであれば `ipconfig` コマンドで確認できます。
2. Dockerイメージを構築する。
```shell
docker-compose build
```
3. `http://localhost/?page=admin§ion=Dashboard` にアクセスしWhitelistにタイトルを追加する。
- username:'admin', password:'opensesame'
- docker-compose.ymlで変更もできます。
| タイトル | コード |
| ---- | ---- |
| ダイヤモンド | ADA |
| パール | APA |
| プラチナ | CPU |
| ハートゴールド | IPK |
| ソウルシルバー | IPG |
4. DS側でDNSサーバーとして先ほど調べたIPアドレスを指定してやる。
## おわりに
以上の手順で、自宅のPCに比較的クリーンで個人的には倫理観に反しないWi-Fiコネクション代替サーバーを構築することができるようになりました。規定数勝利するとリボンを受け取ることができることも確認しています。
対戦相手として[ここ](https://github.com/mm201/pkmn-classic-framework/blob/master/gts/src/FakeOpponentGenerator4.cs)で確認できるダミーデータを受信しますが、不正なポケモンではないと思います。かなり強いので対策が要ります。

結局私の言うクリーンかそうでないかは自己満足で、正規と呼ぶにはもちろんほど遠く、少なくとも想定されていない遊び方でありグレーというには十分黒いことは理解しています。とはいえいずれにせよ、もう二度と公式のサーバーが建つことはない上に復刻も有り得ないのですから、私はこれで収集していくつもりです。