Minecraftサーバー(Spigot)を構築していい感じに設定する

# はじめに

最近、Minecraftサーバー(Spigot[^1])を運営し始めたので、その動作環境と設定や導入したプラグインについて書こうと思います。
**ぼくのかんがえたさいきょうのマイクラサーバー**を披露します。

- Minecraft (Spigot) 1.14.4
- バニラ
- ホワイトリスト制
- チャット日本語化
- その他色々

既にサーバーの構築が終わっている方は[サーバーの設定](#サーバーの設定)や[プラグインの導入](#プラグインの導入)からご覧ください。

# サーバーの構築

Minecraftサーバーとして公式よりも高機能と言われているSpigotサーバーを導入します。

## 環境

GCPの無料枠[^2]を活用して以下の環境を作成しました。なんの変哲もない環境で変な設定もしていません。

- Ubuntu 18.04.3 LTS
- n1-standard-1 (CPU 1 | 3.75 GB)

## インストール

Spigotを動かすにはJava 8 以上が必要[^3]なのでインストールします。

```bash
sudo apt-get install openjdk-8-jre-headless
```

無事Javaがインストールできたら、Spigot本体をビルドします。
https://www.spigotmc.org/wiki/buildtools/ の手順に従って進めていきました。
以下ように実行すると`1.14.4`のサーバーが手に入ります。

```bash
wget https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
java -jar BuildTools.jar --rev 1.14.4
```

大人の事情[^4]により<font color="red">**必ずユーザーがビルドしなければならない**</font>ようです。
ところが、https://getbukkit.org/download/spigot に堂々とビルド済みファイルが置いてあります。
結果として`spigot-1.14.4.jar`のような実行ファイルが手に入れば成功です。

## 初回起動

```bash
java -jar spigot-1.14.4.jar
```

初回起動するとすぐに終了すると思います。

実行ファイルと同じディレクトリに`eula.txt`が生成されるので、ライセンス条項[^5]に同意できる場合は編集して`eula=false`となっている部分をtrueに書き換えます。

```:eula.txt
#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
#Sun Sep 01 00:00:00 UTC 2019
eula=true
```

もう一度`spigot-1.14.4.jar`を起動するとワールドが生成されサーバーが接続待機状態となります。

## 公開

Minecraftサーバーは25565番ポートで動作するので、25565番ポートを開放して、マシンのグルーバルIPを伝えるとアクセスすることができます。更に今回は所有していたドメインのサブドメインを作ってAレコードを登録しました。

| Name | TTL | Type | Value |
|---|---|---|---|
| craft.example.com | 3600 | A | xxx.xxx.xxx.xxx |

これでドメインを使ってサーバーに接続できます。
ポート開放やドメイン設定が面倒な場合はそれらを使わないサーバーの公開方法もあります。そこでよくHamachi[^6]を使った方法が紹介されていますが、個人的にはngrok[^7]を使うのがおすすめです。

## 起動スクリプトの作成

与えるメモリの容量を指定してバックグラウンドでサーバーを起動するスクリプトを作ります。
バックグラウンド実行のためにscreen[^8]をインストールします。

```bash
sudo apt-get install screen
```

以下のようなMakefileを作成しました。

```makefile:Makefile
start:
	screen -d -m -S "spigot" java -Xms1G -Xmx2G -XX:+UseConcMarkSweepGC -jar spigot-1.14.4.jar
```

これで、`make start`でサーバーを起動できます。

# サーバーの設定

要求を満たすようにサーバーの設定を変更していきます。

## 基本設定

`server.properties`を以下のように変更しました。重要なのはホワイトリスト化したことだけで、それ以外は個人的な趣味です。

```properties:server.properties
# 見栄を張って最大接続数を少し増やしました
max-players=32
# 安全のためホワイトリスト制に変更
white-list=true
# サーバー紹介文を変更
motd=A Minecraft Server \u00A79[version 1.14.x] By Spigot
```

`spigot.yml`の`restart-script`を自作の起動スクリプトに変更しています[^9]。

```yaml:spigot.yml
settings:
  restart-script: make start
```

## ホワイトリスト追加

前項でホワイトリスト化したので、基本的にはホワイトリストにユーザーを追加しなければサーバーに接続できません。
サーバーのコンソールから[username]に追加したいユーザー名指定して以下コマンドを実行します。screenを使っている場合は`screen -r`でアタッチして<kbd>Ctrl-A</kbd> <kbd>D</kbd>でデタッチできます。

```
whitelist add [username]
```

# プラグインの導入

Spigotサーバーは`./plugins/`の中に実行ファイルを配置するだけで簡単にプラグインの導入ができます。

## LunaChat

チャンネルチャットプラグインらしい[^10]ですが、主にゲーム内のチャットを日本語化するために導入しました。
チャットにローマ字入力すると以下のように変換されます。
![luna1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65493/2059438c-91ce-79c2-4ac2-000f5ed002b7.png)

https://github.com/ucchyocean/LunaChat/releases から`LunaChat.jar`をダウンロードして、`./plugins/`の中に配置します。
サーバーを再起動すると`./plugins/LunaChat/`の中に設定ファイルが作られています。
例えば`config.yml`の`ngword`には<font color="red">**デフォルト**</font>で以下のようなNGワードが設定されています。

```yaml:config.yml
ngword: ['ちん(こ|ぽ|ちん)']
```

これに該当するワードをチャットで発言すると伏せ字になります。
![luna2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65493/0efffdf4-a111-65c0-cf68-fa9a7b2149ab.png)
当サーバーでは言論の自由を尊重するためNGワードは取っ払っておきました。

## LegendaryMessages

ゲーム内の各種メッセージを独自に変更できるプラグイン[^11]です。
これを利用して接続・切断時メッセージをオリジナルにしました。
![legend.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65493/5297f46d-eb76-7f26-fc46-220154d8e7c8.png)

https://dev.bukkit.org/projects/joinmessages/files から`LegendaryMessages.jar`をダウンロードして、`./plugins/`の中に配置します。
サーバーを再起動して`./plugins/LegendaryMessages/`の中の`config.yml`を編集して以下のようにしました。

```yaml:config.yml
Returning_Join_Message:
  Message: '&d%player_name% さん登場！！ヽ(｀▽´)/'
Quit_Message:
  Message: '&d%player_name% さんがお帰りです(´・ω・｀)'
```

## Slack

MinecraftサーバーとSlackと連携するプラグイン[^12]です。
誰かがサーバーに接続するとSlackのチャンネルにメッセージを送るようにしました。
![slcak.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65493/436f330b-e858-6bbb-df6b-f69170771058.png)

まず、https://my.slack.com/services/new/incoming-webhook にアクセスしてSlackのWebhook URLを取得します。
次に、https://github.com/mastercoms/SlackMC/releases から`Slack.jar`をダウンロードして、`./plugins/`の中に配置します。
サーバーを再起動して`./plugins/Slack/`の中の`config.yml`を編集してwebhook URLを指定しました。

```yaml:config.yml
webhook: https://hooks.slack.com/services/***/***/***
```

## Minecart Speed Plus

トロッコの速度を変更できるプラグイン[^13]です。
以下のようなを設置するとトロッコの速度を定数倍できます。
![msp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65493/db579370-41fa-8ef2-a3ee-706bd47f7311.png)

https://www.spigotmc.org/resources/minecart-speed-plus.69639/ から`MinecartSP.jar`をダウンロードして、`./plugins/`の中に配置します。
プレーヤーにトロッコの速度を変更させるには権限を与える必要があるので、`permissions.yml`に適当な権限を作って`msp.signs`を許可してやります。

```yaml:permissions.yml
server.basics:
  description: Basic permissions
  default: true
  children:
    msp.signs: true
```

サーバーを再起動すると看板を用いてトロッコの速度が変更できるようになっています。

## Dynmap

ブラウザから閲覧できるマップを導入するプラグイン[^14]です。
Minecraftの世界がGoogle MapのようなUIで眺められるようになると思うといいと思います。
![dynmap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65493/d6f05596-a1a3-e718-972f-fbaa04e6bf54.png)

https://github.com/webbukkit/dynmap/releases から`MinecartSP.jar`をダウンロードして、`./plugins/`の中に配置します。
サーバーを再起動して、コンソールから以下のようなコマンドを実行するとマップの描画が始まります。

```
dynmap fullrender world
```

Dynmapは8123番ポートで動作するので、8123番ポートを開放してブラウザから`http://[IP Address]:8123`にアクセスすることで閲覧できます。
しかし、8123番ポートにアクセスするのはどうもイケてないような気がしたので、リバースプロキシを使ってサブディレクトリに80番ポートで公開することにしました。

WebサーバーのNginx[^15]をインストールします。

```bash
sudo apt-get install nginx
```

`/etc/nginx/nginx.conf`を編集して`/etc/nginx/sites-enabled/`をincludeしないようにコメントアウトします。

```conf:/etc/nginx/nginx.conf
http {
  ...
  include /etc/nginx/conf.d/*.conf;
  # include /etc/nginx/sites-enabled/*;
}
```

`/etc/nginx/conf.d/`の中に適当な名前のファイルを作成して、`/dynmap`にアクセスしたときにDynmapが表示されるように設定します。

```conf:/etc/nginx/conf.d/minecraft.conf
server {
  listen 80;
  listen [::]:80;
  server_name minecraft;
  # `/dynmap`にアクセスすると8123番ポートのDynmapに繋がります
  location /dynmap/ {
    proxy_pass http://localhost:8123/;
  }
  # `/`にアクセスするとホームページが表示されます
  location / {
    root /home/xxxxx/web;
  }
}
```

`root`で指定したディレクトリに適当な`index.html`を追加してホームページを作っておきます。

```html:~/web/index.html
<h1>Welcome to My Server</h1>
<a href="./dynmap">Dynmap</a>
```

Nginxを再起動すると`http://[IP Address]/dynmap`でマップが閲覧できるはずです。

```bash
sudo nginx -s reload
```

# 最後に

備忘録も兼ねて運営しているサーバーが今の状態になるまでに行ったことをすべて書いてみました。
自分と同じような要求でMinecraftサーバーを運営したいと思っている方々のお役に立てれば幸いです。


[^1]: [機能を拡張したしたラッパータイプのサーバーMOD](https://www.spigotmc.org/wiki/about-spigot/)
[^2]: [12か月間$300分の無料トライアルが付いてきます](https://cloud.google.com/free/docs/gcp-free-tier)
[^3]: [Spigot Installation](https://www.spigotmc.org/wiki/spigot-installation/)
[^4]: [DMCA問題を回避するためとのことです](https://bukkit.org/threads/bukkit-dmca-whats-going-on.309372/)
[^5]: [MINECRAFT エンド ユーザー ライセンス条項](https://account.mojang.com/documents/minecraft_eula)
[^6]: [仮想プライベートネットワークを実現するソフトウェア](https://www.vpn.net/)
[^7]: [ネットワークを外部公開できるサービス](https://ngrok.com/)
[^8]: [CLI版ウインドウマネージャー](https://www.gnu.org/software/screen/manual/screen.html)
[^9]: 一度もサーバーが落ちたことがないので動作は未確認ですが
[^10]: [LunaChat](https://github.com/ucchyocean/LunaChat)
[^11]: [LegendaryMessages](https://dev.bukkit.org/projects/joinmessages)
[^12]: [SlackMC](https://github.com/mastercoms/SlackMC)
[^13]: [Minecart Speed Plus](https://www.spigotmc.org/resources/minecart-speed-plus.69639/)
[^14]: [Dynmap](https://github.com/webbukkit/dynmap)
[^15]: [大変有名なWebサーバー](https://nginx.org/)