RaspberryPiでテラリアサーバを立てる

　最近友人に勧められテラリアをしましたが非常に面白いですね。2D版マイクラと言われていますが、マイクラにはない要素がてんこ盛りで驚きました。ただこのゲームでホスト&プレイによってマルチプレイをすると、（当たり前ですが）ホスト側が起動しないと友人たちがプレイできないんです。そこで安価な小型PCである**RaspberryPi3 ModelBを使用してサーバとして稼働させてしまおう**と思い実際に頑張りました。しかしながらいろいろ躓き、結果、丸一日ほどかけて構築できたため未来のテラリアンのためにここに書き残そうと思います。
　UNIX系OSをあまり知らない人を想定して書いているため**長い**です（自分がそうですので）。初投稿なため、少々見にくいかもしれませんがご容赦ください。

#1. 目的
　RaspbianをインストールしたRaspberryPi3 ModelB（以降ラズパイと表記）に身内で使用するテラリア用のサーバ環境を構築する。
#2. 条件等
　少し前にちょっと触って放置していたラズパイを引っ張り出しました。そのため明確な前提条件が書けませんが、以下のような感じだと思います。

- ラズパイにOSはインストール済み
- SSH接続が可能(ディスプレイ等が余っているならば直接でもOK)

また、今回のサーバは友人とやる目的であるため

- サーバは公開しない(ポート開放をしない)
- HamachiによるVPNを使った通信

で稼働させます。

**追記(11/11)：**
**今回使用したラズパイのOSは以下の通りです。**

~~~
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 8.0 (jessie)
Release:        8.0
Codename:       jessie
~~~

　　***参考：[Raspberry Pi でOS（Raspbian）のバージョンを調べる](https://qiita.com/fujit33/items/16ce964c228a63a9d8dd)***
**追記終了**

#3. 手順
　ざっくりとした手順は以下の通りです。

1. wget, mono, screenのインストール
2. TShockのインストール
3. ワールドデータのクラウド共有
4. Hamachiのインストール

上記の手順3に関しては今までホストでやっていたデータを持ってくるだけなので、別の方法でも問題ない上にラズパイで生成することも可能です。ただし生成には結構時間がかかります。

　またコマンド入力を少なくするために管理者権限を先に取得します。（`Tab`使えば良い話ですが…）

~~~
sudo su
~~~

##3.1 wget, mono, screenのインストール
　環境構築に`apt-get`と`wget`を使用します。確か`apt-get`は最初から入ってましたが、`wget`は入っていなかったと思うためインストールします。

~~~
apt-get install wget
~~~
テラリアのサーバプログラムを実行するため、monoをインストールします。インストールに10分ほどかかりました。

~~~
apt-get install mono-complete
~~~
SSHなどから起動し`exit`で切断した際にバックグラウンドでサーバプログラムを稼働させるために`screen`をインストールします。

~~~
apt-get install screen
~~~

##3.2 TShockのインストール
　当初「*テラリア ラズパイ*」で検索し、ヒットした日本語サイトの通りにインストールしましたが、 **バニラサーバ(通常のサーバ)を入れると実行時やクライアント接続時にエラーを吐きました**。`SocketException`等と例外が出ていたため、プログラム内部の問題かと思いますが、正直よく分からなかったため英語サイトで紹介されていたTShockを入れました。

　*参考サイト：[How to set up a Raspberry Pi Terraria Server](https://pimylifeup.com/raspberry-pi-terraria-server/)*

　はじめに、テラリア用のディレクトリを作ります。お作法等があるとは思いますが私はどこでも良いと思い、デフォルトユーザ直下に「terraria」ディレクトリを作りました。`mkdir`でディレクトリを作成し、`cd`で指定のディレクトリに移動です。

~~~
mkdir /home/pi/terraria
cd /home/pi/terraria
~~~

　次にTShockを`wget`でダウンロードしますが、その前に最新バージョンのURLを確認するためにGitHubに行きます。
　　→ [Releases・Pryaxis/TShock・GitHub](https://github.com/Pryaxis/TShock/releases)
以下の画像のようにリリースノートが書かれていると思います。緑色でLatest releaseと書かれたページ内のAssetsの真下にある*tshock_○.○.○○.zip*のURLをコピーしましょう（FireFoxならば右クリック→リンクのURLをコピー）。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/311823/b14e8cf4-eaa6-881f-0693-921c6b11baad.png)

2018年11月現在では画像のように4.3.25が最新でしたのでこのURLに対して`wget`コマンドを実行します。
（Tera Termで接続していると`wget`とスペースを打った後にコンソールを右クリックで以下のようなコマンドが打てます。）

~~~
wget https://github.com/Pryaxis/TShock/releases/download/v4.3.25/tshock_4.3.25.zip
~~~
*※以降のTShockのバージョンは4.3.25を前提として説明しますので、バージョンが異なる場合は適宜読み替えてください。*

コマンドが完了するとterrariaディレクトリに「tshock_4.3.25.zip」ファイルがダウンロードされます。このファイルをzip解凍します。`unzip`を実行します。

~~~
unzip tshock_4.3.25.zip
~~~

解凍が完了し、`ls`でディレクトリ内のファイルを確認すると以下のようになっていると思います。

~~~
root@raspberrypi:/home/pi/terraria# ls
GeoIP.dat  Newtonsoft.Json.dll  OTAPI.dll  ServerPlugins  TerrariaServer.exe  sqlite3.dll  tshock_4.3.25.zip
~~~

### ＝＝＝ここまでの手順でサーバの導入は完了です＝＝＝

　zipファイルは必要ないので`rm`で削除しちゃいましょう。

~~~
rm tshock_4.3.25.zip
~~~

　以下のコマンドで実行できるか試してみましょう。実行確認が出来たら`Ctrl+C`で強制終了できます。もちろんこのままワールドデータを作成して、SSHしているPCからIP経由でアクセスすればプレイできます。ただしこのままでは友人はアクセスできません。

~~~
mono TerrariaServer.exe
~~~

実行中は以下のように表示されます。（起動に少々時間がかかります。）
うまく起動できると、ワールド選択が促されます。

~~~
root@raspberrypi:/home/pi/terraria# mono TerrariaServer.exe
TerrariaAPI Version: 2.1.0.0 (Protocol v1.3.5.3 (194), OTAPI 1.3.5.3)
TShock was improperly shut down. Please use the exit command in the future to prevent this.
TShock 4.3.25.0 (Mintaka) now running.
AutoSave Enabled
Backups Disabled
Welcome to TShock for Terraria. Initialization complete.
[Server API] Info Plugin TShock v4.3.25.0 (by The TShock Team) initiated.
~~~

##3.3 ワールドデータのクラウド共有
　次に今までWindowsで遊んでたワールドデータをラズパイに持ってきます。「新しくワールドデータ作るよ！」や「宗教上の理由でクラウドはちょっと…」等であれば、手順3.4に飛んで下さい。

　**以下はWindowsでの操作です**。

###3.3.1 ワールドデータのディレクトリ
Windows10では以下のディレクトリにテラリアのデータがあります。

~~~
C:\%USERNAME%\Documents\My Games\Terraria
~~~
→ [他OSの場合(terraria - Where are my world files?)](https://gaming.stackexchange.com/questions/133958/where-are-my-world-files)

このディレクトリ内にWorldsフォルダがあると思います。この中にwld形式のワールドデータがあります。

###3.3.2 mklink(Windows)によるワールドデータのクラウド共有
　*参考サイト：[TerrariaのセーブデータをDropboxで同期管理](http://www.cho-design-lab.com/2013/06/01/terraria-dropbox/)*

　mklinkコマンドを使うと、簡単に言えばショートカットの強化版のようなものが作れます。iTunesのバックアップなど「ディレクトリがアプリ側から強制的に決まってるけど実際に存在する場所を移動させたい！」というときによく使います。

　エクスプローラを使ってワールドデータを切り取り&貼り付けでクラウド共有フォルダに移動します。そして以下のようなコマンドをコマンドプロンプトで実行します。

~~~
mklink /d "C:\%USERNAME%\Documents\My Games\Terraria\Worlds" "[クラウド共有フォルダのディレクトリ]"
~~~

このとき、テラリアのデータにWorldsフォルダが存在するとエラーとなりますので、フォルダ名を「Worlds_bakcup」などとリネームしましょう。

　**※よく分からなければ手順3.3.1で確認した「wldファイル」を自身のクラウドにアップロードするだけでOKです**
（これをやるとクラウドに自動アップロードできるため便利ってだけです）。

###3.3.3 クラウドでデータを取得
　クラウドにアップロードしたwldファイルをリンク共有をし、リンクURLを取得します。Dropboxの場合は、右クリックし`Dropbox リンクをコピー`とするだけです。

　ラズパイに戻り以下のコマンドを実行することで、ワールドデータを取得することが出来ます。ちなみに`-O`オプションは保存ディレクトリと保存ファイル名の指定です。これを指定しないと、ファイル名が悲しいことに…

~~~
wget [リンクURL] -O /root/.local/share/Terraria/Worlds/[ワールド名].wld
　↓ 実際にはこんな感じ
wget https://www.dropbox.com/x/xxxxxxxxxxx/[ワールド名].wld?dl=0 -O /root/.local/share/Terraria/Worlds/[ワールド名].wld
~~~

##3.4 Hamachiのインストール
　簡単にVPNが出来るHamachiを使います。ただしプレイするには**クライアント側も全員Hamachiをインストールして、同じネットワークに参加しなければなりません**。またちょっとした**アカウント登録も必要です**。
　ちなみにVPNとはインターネットを通じて仮想的にローカルネットワークを構成する技術です。

　*参考サイト：[Raspberry PiにHamachiのインストール及び自動起動](http://kinokotimes.com/2016/09/27/raspberry_pi_hamachi_install/)*

　インストールは参考サイトそのままです。ただし自動起動に関しては**rc.localに記述しても実行してくれなかった**ため、Hamachiにログインするシェルスクリプトを書き、**crontabの`@reboot`で動かしました**。rc.localに記述して起動時に自動実行するならば手順3.4.2は読み飛ばしてもらって構いません。
###3.4.1 インストール


　lsbとlsb-coreをインストールします。

~~~
apt-get install --fix-missing lsb lsb-core
~~~

以下のサイトにアクセスし、最新バージョンのURLを確認してwgetで取得します。ページ下部のファイル名が*logmein-hamachi_○.○.○.○-○_armhg.deb*となっているファイルのリンクをコピーしましょう。

→ [Hamachi for Linux](https://www.vpn.net/linux)
![2.png](https://qiita-image-store.s3.amazonaws.com/0/311823/b58ea51e-9c15-defd-1d2b-fe1c09ba6252.png)

2018年11月現在、最新バーションは画像の通り2.1.0.198-1でしたので、以下のコマンドを実行します。

~~~
wget https://www.vpn.net/installers/logmein-hamachi_2.1.0.198-1_armhf.deb
~~~

ダウンロードしたファイルをインストールします。このとき間違ったファイルをダウンロードしているとエラーが出ます。

~~~
dpkg -i logmein-hamachi_2.1.0.198-1_armhf.deb
~~~

これでインストールが完了します。

###3.4.2 実行確認とネットワーク作成 
以下のコマンドで実行します。上手くいけば`starting - success`が表示されるはずです。

~~~
/etc/init.d/logmein-hamachi start
~~~

*※これ以降の手順はHamachiのアカウントを各自用意してください。*
→ [LogMeIn アカウント](https://accounts.logme.in/registration.aspx?lang=ja-JP)

　登録したアカウント情報を基に以下のコマンドを実行します。attachコマンドを実行した際にパスワードを聞かれた気がしますので、一行ずつ実行した方が良いと思います。なお、**アカウントはクライアント側のPCと共有しても大丈夫なようです**。

~~~
hamachi login
hamachi attach [メールアドレス]
hamachi set-nick [Hamachi内の表示名]
~~~

ネットワークを作ります。以下のコマンドから自由にネットワークIDとパスワードを決めて実行しましょう。ただしネットワークIDは短いと既に使われている可能性があるので、そこそこ長めにしましょう。作成に成功すると`Creating [ID] .. ok`と表示されます。

~~~
hamachi create [ネットワークID] [パスワード]
~~~

*※作成したネットワークのネットワークIDとパスワードはクライアントが参加するのに必要なため、友人に知られても良いパスワードにしましょう*

`hamachi list`コマンドで作成されたネットワークを以下のように確認できます。

~~~
root@raspberrypi:/home/pi/terraria# hamachi list
 * [ネットワークID]  capacity: 1/5, subscription type: Free, owner: This computer
~~~

作ったネットワークが気に入らなかった場合は`hamachi delete [ネットワークID]`で削除できます。

~~~
root@raspberrypi:/home/pi/terraria# hamachi delete [ネットワークID]
Deleting [ネットワークID] .. ok
~~~

###3.4.3 自動起動設定
 ネットワーク作成後、次回ラズパイを起動した際には

~~~
/etc/init.d/logmein-hamachi start
hamachi login
~~~
と、コマンドを実行するだけですが、これもめんどくさいのでcrontabによる自動起動設定をします。

　最初に`nano`を使って`hamachi.sh`ファイルにコマンドを記入します。

~~~
nano hamachi.sh
~~~

以下のように記入します。

```shell:hamachi.sh
#!/bin/sh

/etc/init.d/logmein-hamachi start
hamachi login

exit 0
```
記入し終えたら`Ctrl+X`を押して終了し「保存しますか」と聞かれるので`Y`を押しましょう。その後、ファイル名を入力しますが、そのまま`Enter`を押して保存完了です。

　続いて`crontab`に登録します。以下のコマンドを入力すると、初回起動時にエディタ選択を聞かれますので、`nano`を選びましょう。私の環境では2番目にnanoがあったため、`2`と入力しました。そして以下のように`@reboot /home/pi/terraria/hamachi.sh`を追記します。

~~~
crontab -e
~~~

```shell:crontab
# Edit this file to introduce tasks to be run by cron.
#
#　　　　　　　　~ 省略 ~
#
# m h  dom mon dow   command

@reboot /home/pi/terraria/hamachi.sh
```
追記し終えたら、先ほどと同様に保存して終了します。`crontab: installing new crontab`と表示されたらOKです。

　`reboot`で再起動して確認します。もちろんSSHが切断されますが、ラズパイのLANポートがピカピカ光りだしたらSSH接続し直しましょう。

~~~
reboot
~~~

　先ほどの自動起動設定がちゃんとしていれば、`hamachi list`を実行するとしっかりとネットワークが表示されるはずです。その前に、`sudo su`で管理者権限を取得しておくのを忘れずに。

~~~
pi@raspberrypi:~ $ sudo su
root@raspberrypi:/home/pi# hamachi list
 * [ネットワークID]  capacity: 1/5, subscription type: Free, owner: This computer
~~~

# 4. 実際に遊んでみる
　実際にTShockを起動して、クライアントを参加させて遊んでみます。手順は以下の通りです。

1. screenの起動
2. サーバの起動
3. クライアントがHamachiに参加
4. IP経由でプレイ

## 4.1 screenの起動
バックグラウンドで稼働できるようにscreenを起動します。何かいろいろ出てきますが、気にせず`Enter`を押します。

~~~
screen
~~~

## 4.2 サーバの起動
サーバを起動します。

~~~
cd /home/pi/terraria
mono TerrariaServer.exe
~~~

以下のようにワールド選択を聞かれるので、

- クラウドからダウンロードしたならば`1`
- 新しく作るならば`n`

を入力しましょう。

~~~
Terraria Server v1.3.5.3

1           [ワールド名]
n       New World
d <number>Delete World

Choose World:
~~~

最大プレイ人数を聞かれます。友達が多ければその人数を入力しましょう。

~~~
Terraria Server v1.3.5.3

Max players (press enter for 8):
~~~

使用するポート番号を聞かれます。VPNで接続しているのでなんでも大丈夫ですが、クライアントもこれを入力するためデフォルトの7777を使いましょう。デフォルトの場合は`Enter`を入力するだけでOKです。

~~~
Terraria Server v1.3.5.3

Server port (press enter for 7777):
~~~

ポートフォワーディングについて聞かれます。分からないので`Enter`を押しましょう。

~~~
Terraria Server v1.3.5.3

Automatically forward port? (y/n):
~~~

パスワードの設定を聞かれます。任意でも構いませんし、VPN上でやっているため未設定でも特に問題ないかと思います。未設定にする場合はそのまま`Enter`を押しましょう。

~~~
Terraria Server v1.3.5.3

Server password (press enter for none):
~~~

ワールドデータを読み込み、サーバが稼働します。

~~~
Terraria Server v1.3.5.3

Resetting game objects 1%
Resetting game objects 2%
Resetting game objects 3%
Resetting game objects 4%
Resetting game objects 5%
            :
~~~

以下が表示されたら、サーバの稼働に成功したことになります。

~~~
Terraria Server v1.3.5.3

Listening on port 7777
Type 'help' for a list of commands.

:

~~~

`screen`によって`Ctrl+A → D`と押すとバックグラウンドで稼働させることが出来ます。入力すると`[detached from [番号].pts-1.raspberrypi]`の後にいつものプロンプトが表示され、何もないように見えますが、`screen -ls`と入力すると稼働していることが分かります。

~~~
root@raspberrypi:/home/pi/terraria# screen -ls
There is a screen on:
        [番号].pts-1.raspberrypi  (2xxx年xx月xx日 xx時xx分xx秒)   (Detached)
1 Socket in /var/run/screen/S-root.
~~~

　**バックグラウンドで稼働させた状態でSSH接続を切断しても、電源が入っている限り稼働し続けます**。つまり友人も自由に入れるわけです。

　サーバのコマンドラインに戻りたいときは、`screen -r [番号]`で戻ることが出来ます。もし、上記のように`[番号]`が一つ分しかなかった場合は`screen -r`で戻ることが出来ます。

~~~
root@raspberrypi:/home/pi/terraria# screen -r

      ↓切り替わる↓

Terraria Server v1.3.5.3

Listening on port 7777
Type 'help' for a list of commands.

:
~~~

`screen`の詳しい使い方は@hnishi様が書かれた投稿をご覧ください。
→ [Linux screenコマンド使い方 - Qiita](https://qiita.com/hnishi/items/3190f2901f88e2594a5f)

##4.3 クライアントがHamachiに参加
　クライアントのPCにHamachiをインストールし、各自登録したアカウントでログインします。
ログイン後、`ネットワーク → 既存のネットワークに参加`と選択し、ラズパイで設定したネットワークIDとパスワードを入力します。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/311823/2d08b29e-6682-bb12-0820-f83f6eb1c358.png)

ネットワークの参加に成功すると、設定したネットワークIDの中にラズパイが接続されていることが確認できます。ラズパイのIPv4アドレスを控えます。Terrariaを起動し、`マルチプレイ → IP経由での参加 → キャラ選択`と進みます。サーバIPの欄に先ほど控えたIPを入力します。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/311823/033dbf4e-562f-c1fc-0777-a2d2f4ae253d.png)

サーバポート番号も設定した番号を入力します。デフォルトならば7777なのでそのまま進みます。

上手くいくと、通常のマルチプレイのようにデータを受信してプレイできます。
そしてサーバ側のコマンドラインには

~~~
: xx.xx.xx.xx:xxxxx is connecting...
[playerName] authenticated successfully as user [playerName].
[playerName] has joined.
~~~

と表示されているはずです。もしサーバが稼働しているのに「接続します（Connecting to） [IPアドレス]」で止まっている場合は、IPアドレスかポート番号が間違えている可能性があります。再度確認してみてください。

　TShockは荒らし対策による権限関連の関係で初期設定を多少必要としますので、wikiなどを参考にセットアップしてみてください。
→ [TShock 公式wikiの和訳](http://terraria.arcenserv.info/wiki/TShock_%E5%85%AC%E5%BC%8Fwiki%E3%81%AE%E5%92%8C%E8%A8%B3)

#5. 結論
　何とか環境を構築することが出来ました。サーバを立てるのは初めてだったため非常に大変でしたが、しっかりと目的は達成することが出来ました。大体同じ手順で、VPSにも構築できると思っています。

　以上でこの記事は終了です。最後までお読みいただきありがとうございました。