【GCP】統合版MinecraftサーバーをGCEで建てる3【統合版Minecraft】

# 概要
GCPに構築した統合版Minecraftサーバーの課題対応その２。

今回は、設計やコードではなく、Minecraftサーバーそのものについての変更対応。

# 目的
+ サーバー建てたら意外と需要があったので、複数ワールド対応を試みる。
+ 複数ワールド化出来れば、家を建てたりして生活するワールドと、資源を集めに行くためのワールド（枯渇したらリジェネレートすればいい）を分けたり出来る。
+ IaC化しているのでサーバー台数増やせば手っ取り早いけど、それではコスト増加するし、クライアント側での設定が面倒になるので避ける。
+ 接続先は１つで、簡単にワールド切り替え出来るのが望ましい。

# 事前調査
+ **複数ワールド対応について**
前提として、公式配布されている統合版Minecraftサーバーでは、複数ワールドを作成したり、それらを起動時に切り替えることは出来るが、同時に複数ワールドを起動して行き来するようなことは出来ないっぽい。
それを実現するには、プラグイン対応の非公式サーバーが必要そう。

+ **プラグイン対応非公式サーバー**
派生が多すぎてわけわからん…。
が、とりあえずいろいろ調べた結果、統合版であれば「PMMP」というのが老舗で現状も更新されておりプラグインの数も多そうだったので、こちらを採用することにする。
ちなみに統合版はかなり選択肢が少なく、主流はJAVA版のようだった。
Switchからの接続がメインになるのでJAVA版は採用出来ない。
一応、「JAVA版サーバーに、統合版クライアントを接続出来るようにする」プラグインやらプロキシサーバーやらはあるようだったが、一部機能が再現出来ていないなど制限もあるようだったので、こちらも非採用。


# 1. 構築
構築済みの統合版Minecraftサーバー（公式）を、PMMPに置き換える。

## 1.1. コード修正
Minecraftサーバーの構築は、cloud-init（cloud-config）で実施しているので、そこを修正。

<details><summary>service01\templates\cloud-init.yaml</summary><div>

```service01\templates\cloud-init.yaml
#cloud-config
timezone: Asia/Tokyo
locale: ja_JP.utf8
packages:
  - unzip
  - zip
  - expect

users:
  - name: 'minecraft'
    plain_text_passwd: 'minecraft'
    shell: '/bin/bash'
    sudo: 'ALL=(ALL) NOPASSWD:ALL'
    lock_passwd: false

# init command
runcmd:
  - gcloud auth application-default login
  - mkdir /opt/minecraft
  - mkdir /opt/minecraft/pmmp
  - chown -R minecraft:minecraft /opt/minecraft
  - mv /home/minecraft/mcs_backup.sh /opt/minecraft/pmmp/mcs_backup.sh
  - mv /home/minecraft/pmmp_init.sh /opt/minecraft/pmmp/pmmp_init.sh
  - cd /opt/minecraft/pmmp
  - "wget -q -O - https://get.pmmp.io | sudo -u minecraft bash -s -"
  - sudo su minecraft ./pmmp_init.sh
  - "wget -P /opt/minecraft/pmmp/plugins https://poggit.pmmp.io/r/152903/MultiWorld.phar"
  - "wget -P /opt/minecraft/pmmp/plugins https://poggit.pmmp.io/r/163649/AllSigns.phar"
  - "wget -P /opt/minecraft/pmmp/plugins https://poggit.pmmp.io/r/122340/PureEntitiesX.phar"


write_files:
    - path: /home/minecraft/mcs_backup.sh
      content: |
        #!/bin/bash
        BACKUP_BUCKET='gs://hoge-mcs_backup_backet-dev/'

        screen -r pmmp -X stuff '/save-all\n/save-off\n'
        /usr/bin/zip -r ${BASH_SOURCE%/*}/worlds.zip ${BASH_SOURCE%/*}/worlds
        /snap/bin/gsutil cp -R ${BASH_SOURCE%/*}/worlds.zip ${BACKUP_BUCKET}
        /bin/rm ${BASH_SOURCE%/*}/worlds.zip
        screen -r pmmp -X stuff '/save-on\n'
      permissions: '0755'
      owner: root:root
    - path: /home/minecraft/pmmp_init.sh
      content: |
        #!/bin/bash
        timeput=20                      # 言語
        lang="jpn"                      # 言語
        licence="y"                     # Licence同意
        setup_wizard="N"                # 
        server_name="Hiko Game Server"  # 
        ipv4_port=19132                 # 
        ipv6_port=19133                 # 
        default_game_mode=0             # 0=サバイバルモード、1=クリエイティブモード
        max_players=20                  # 
        max_view=16                     #
        op_name="hoge"                  #
        white_list="N"                  #
        disabled_query="N"              #

        expect -c "               # expect コマンドを実行
        set timeout ${timeput}
        spawn sudo su minecraft ./start.sh  # expect コマンドの管理下でstart.shを実行する
        expect \"Language (eng):\"  ; send \"${lang}\n\"
        expect \"ライセンスに同意しますか？ (y/N):\"  ; send \"${licence}\n\"
        expect \"セットアップウィザードをスキップしますか？ (y/N):\"  ; send \"${setup_wizard}\n\"
        expect \"サーバーの名前を付けてください (PocketMine-MP Server):\"  ; send \"${server_name}\n\"
        expect \"Server port (IPv4) (19132):\"  ; send \"${ipv4_port}\n\"
        expect \"Server port (IPv6) (19133):\"  ; send \"${ipv6_port}\n\"
        expect \"デフォルトのゲームモード (0):\"  ; send \"${default_game_mode}\n\"
        expect \"最大オンラインプレイヤー数 (20):\"  ; send \"${max_players}\n\"
        expect \"Maximum view distance (chunks) (16):\"  ; send \"${max_view}\n\"
        expect \"OP プレイヤー名 (例: あなたのゲームの名前):\"  ; send \"${op_name}\n\"
        expect \"ホワイトリストを有効にしますか？ (y/N):\"  ; send \"${white_list}\n\"
        expect \"Query を無効にしますか？ (y/N):\"  ; send \"${disabled_query}\n\"
        "
      permissions: '0755'
      owner: root:root

# reboot
power_state:
  delay: now
  mode: reboot
```
</div></details>


具体的には、下記 runcmd: を変更。
```service01\templates\cloud-init.yaml
runcmd:
  - "wget -P /home/minecraft https://minecraft.azureedge.net/bin-linux/bedrock-server-1.18.12.01.zip"
  - unzip /home/minecraft/bedrock-server-1.18.12.01.zip -d /home/minecraft
  - sed -i".org" -e "s/^server-name=Dedicated Server$/server-name=Hiko Game Server/g" /home/minecraft/server.properties
  - sed -i -e "s/^difficulty=easy$/difficulty=peaceful/g" /home/minecraft/server.properties

　⇓⇓⇓ 下記へ変更 ⇓⇓⇓

runcmd:
  - mkdir /opt/minecraft
  - mkdir /opt/minecraft/pmmp
  - chown -R minecraft:minecraft /opt/minecraft
  - mv /home/minecraft/mcs_backup.sh /opt/minecraft/pmmp/mcs_backup.sh
  - mv /home/minecraft/pmmp_init.sh /opt/minecraft/pmmp/pmmp_init.sh
  - cd /opt/minecraft/pmmp
  - "wget -q -O - https://get.pmmp.io | sudo -u minecraft bash -s -"
  - sudo su minecraft ./pmmp_init.sh
  - "wget -P /opt/minecraft/pmmp/plugins https://poggit.pmmp.io/r/152903/MultiWorld.phar"
  - "wget -P /opt/minecraft/pmmp/plugins https://poggit.pmmp.io/r/163649/AllSigns.phar"
  - "wget -P /opt/minecraft/pmmp/plugins https://poggit.pmmp.io/r/122340/PureEntitiesX.phar"
```
1. PMMP格納フォルダを作成
2. 1の所有権をminecraftユーザーに変更
3. 後述の「write_files:」で作成したスクリプトを1へ移動
4. PMMPを取得し、セットアップスクリプトを実行（するスクリプトを実行）
5. PMMPに導入するプラグインをDL

という処理を行っている。
前回までは、「/home/minecraft」フォルダに諸々格納していたのだがやや違和感を感じていたため、「/opt」配下に変更している。

　
また、write_files: に下記を追記している。

```service01\templates\cloud-init.yaml
    - path: /home/minecraft/pmmp_init.sh
      content: |
        #!/bin/bash
        timeput=20                      # 言語
        lang="jpn"                      # 言語
        licence="y"                     # Licence同意
        setup_wizard="N"                # 
        server_name="Hiko Games Server" # 
        ipv4_port=19132                 # 
        ipv6_port=19133                 # 
        default_game_mode=0             # 0=サバイバルモード、1=クリエイティブモード
        max_players=20                  # 
        max_view=16                     #
        op_name="hoge"                  #
        white_list="N"                  #
        disabled_query="N"              #

        expect -c "               # expect コマンドを実行
        set timeout ${timeput}
        spawn sudo su minecraft ./start.sh  # expect コマンドの管理下でstart.shを実行する
        expect \"Language (eng):\"  ; send \"${lang}\n\"
        expect \"ライセンスに同意しますか？ (y/N):\"  ; send \"${licence}\n\"
        expect \"セットアップウィザードをスキップしますか？ (y/N):\"  ; send \"${setup_wizard}\n\"
        expect \"サーバーの名前を付けてください (PocketMine-MP Server):\"  ; send \"${server_name}\n\"
        expect \"Server port (IPv4) (19132):\"  ; send \"${ipv4_port}\n\"
        expect \"Server port (IPv6) (19133):\"  ; send \"${ipv6_port}\n\"
        expect \"デフォルトのゲームモード (0):\"  ; send \"${default_game_mode}\n\"
        expect \"最大オンラインプレイヤー数 (20):\"  ; send \"${max_players}\n\"
        expect \"Maximum view distance (chunks) (16):\"  ; send \"${max_view}\n\"
        expect \"OP プレイヤー名 (例: あなたのゲームの名前):\"  ; send \"${op_name}\n\"
        expect \"ホワイトリストを有効にしますか？ (y/N):\"  ; send \"${white_list}\n\"
        expect \"Query を無効にしますか？ (y/N):\"  ; send \"${disabled_query}\n\"
        "
      permissions: '0755'
      owner: root:root
```
PMMPは初期セットアップに対話式のスクリプト（start.sh）を使用するため、そこを無人化するスクリプトを自作した。
ただ、起動に必要な最低限の設定しか入らないので、細かく設定したい場合は、上記スクリプト後に作成される「server.properties」ファイルにて追記・修正が必要である。
　
また、下記バックアップスクリプトにて、「worlds」フォルダのパス指定が誤っていた（「/」が足りなかった）ので修正している。
下記記事も修正済み。
[【GCP】統合版MinecraftサーバーをGCEで建てる【統合版Minecraft】](https://qiita.com/Hikoly/items/c9b9d92efc61a14f5dca)

```service01\templates\cloud-init.yaml
    - path: /home/minecraft/mcs_backup.sh
      content: |
        #!/bin/bash
        BACKUP_BUCKET='gs://hoge-mcs_backup_backet-dev/'

        screen -r pmmp -X stuff '/save-all\n/save-off\n'
        /usr/bin/zip -r ${BASH_SOURCE%/*}/worlds.zip ${BASH_SOURCE%/*}/worlds
        /snap/bin/gsutil cp -R ${BASH_SOURCE%/*}/worlds.zip ${BACKUP_BUCKET}
        /bin/rm ${BASH_SOURCE%/*}/worlds.zip
        screen -r pmmp -X stuff '/save-on\n'
      permissions: '0755'
      owner: root:root
```

## 1.2. プラグイン
DLして置くだけなので、前項の cloud-init(cloud-config)にて実施済みだが、最終更新ファイルへのリンクしか記載していないので、一応こちらで紹介しておく。

導入したプラグインは下記。

[MultiWorld](https://poggit.pmmp.io/p/MultiWorld/1.7.0-beta4)（複数ワールド同時起動、ゲーム内でワールド間移動）
An advanced world management PocketMine plugin with custom world generators.

[AllSigns](https://poggit.pmmp.io/p/AllSigns/2.0.2)（ワールド間移動する看板を作成）
Turn signs into world teleport and command signs.

[PureEntitiesX](https://poggit.pmmp.io/p/PureEntitiesX/)（動物やモンスターをスポーンさせる）
Implement Animals and Monsters Into Your Worlds.



## 1.3. 動作確認
PC版、Switch版から問題なくログインやワールド移動が出来ることは確認出来た。

しかし、mobが沸かない……調べても、「プラグインで解決出来る」という意見と「現状無理（沸かない）」という意見の両方が出てきてよくわからない。
おそらくだけど、「PureEntitiesX」が現状のPMMPのバージョンに対応していないのか？？
（起動後に、/plugins コマンドを叩いても出てこない）

実はプラグイン入れずとも元々対応してたりするのか？と期待して、server.propertiesに「spawn-animals=on（もしくはtrue）」や「spawn-mobs=on（もしくはtrue）」を追記してみたりもしたが、状況変わらずだった。


ちょっとコレでは寂しすぎるので、別の方法を考え直さないとだなぁ。