【GCP】Minecraft[1.17]のMODサーバをGCEに構築する

# MinecraftMODサーバを構築

どうやら、FabricとOptifineはすでに1.17に対応しているようなので、
マルチMODサーバも構築する

## 今回インストールするもの

- Fabric installer v0.7.4 (1.17.1まで対応)
- Fabric API v0.36.0 (1.17まで対応)
- Optifabric v1.11.9 (1.17まで対応)
- Optifine_1.17_HD_G9_pre26 (1.17対応)

※2020/07/10 現在で最新は1.17.1だが、Optifabricのみ1.17までなので1.17でそろえる

## インスタンス作成

### terraformでインスタンス起動

- スペック

|               項目 | スペック        |
| -----------------: | :-------------- |
| インスタンスタイプ | e2-standard-4   |
|           ディスク | pd-standard     |
|       ディスク容量 | 20GB            |
|         リージョン | asia-northeast1 |
| プリエンプティブル | オン            |

- tfファイル作成

```tf:main.tf
resource "google_compute_address" "mcs02-ip" {
  name         = "mcs02"
  description  = "external IP for mcs02"
  network_tier = "STANDARD"
  region       = "asia-northeast1"
}

resource "google_compute_instance" "minecraft-mod-server" {
  machine_type = "e2-standard-4"
  name         = "mcs02"
  project      = "[PROJECT_ID]"
  tags         = ["minecraft-server", "internal"]
  zone         = "asia-northeast1-c"
  metadata = {
    "shutdown-script-url" = "gs://[bucket-name]/backup-fabric.sh"
    "startup-script-url"  = "gs://[bucket-name]/startup-fabric-mcs.sh"
  }

  boot_disk {
    auto_delete = true
    device_name = "mcs02"
    mode        = "READ_WRITE"
    initialize_params {
      image  = "https://www.googleapis.com/compute/v1/projects/centos-cloud/global/images/centos-stream-8-v20210512"
      labels = {}
      size   = 20
      type   = "pd-standard"
    }
  }

  network_interface {
    network    = google_compute_network.vpc.name
    network_ip = "10.0.0.4"
    subnetwork = google_compute_subnetwork.public-subnet-1.name
    access_config {
      nat_ip       = google_compute_address.mcs02-ip.address
      network_tier = "STANDARD"
    }
  }

  service_account {
    email = "565378471472-compute@developer.gserviceaccount.com"
    scopes = [
      "https://www.googleapis.com/auth/cloud-platform",
    ]
  }

  scheduling {
    preemptible       = true
    automatic_restart = false
  }
}
```

```sh
$ terraform plan
$ terraform apply
```

## サーバ内作業

### ライブラリ、ミドルウェア等のインストール

- とりあえず

```shell
# dnf -y update
```

- 必要ライブラリインストール

```shell
# dnf -y install make ncurses-devel wget gcc
```
wget : JDK,screnn,MOD類のDLに必要
make , ncurses-devel , gcc : screenのインストールに必要

- OpenJDK16インストール

Minecraft 1.17からはJDKv16以上が必要

```
# cd /usr/local/src
# wget https://download.java.net/java/GA/jdk16.0.1/7147401fd7354114ac51ef3e1328291f/9/GPL/openjdk-16.0.1_linux-x64_bin.tar.gz
# tar xzvf openjdk-16.0.1_linux-x64_bin.tar.gz 
# mv jdk-16.0.1 /usr/local/jdk
# cd /usr/local/bin
# ln -s /usr/local/jdk/bin/java java

$ java -version
openjdk version "16.0.1" 2021-04-20
OpenJDK Runtime Environment (build 16.0.1+9-24)
OpenJDK 64-Bit Server VM (build 16.0.1+9-24, mixed mode, sharing)
```

- screenインストール

```
# cd /usr/local/src && wget http://ftp.gnu.org/gnu/screen/screen-4.8.0.tar.gz
# tar xzvf screen-4.8.0.tar.gz
# cd screen-4.8.0
# ./configure
# make
# cd ../
# mv screen-4.8.0 /usr/local/screen
# cd /usr/local/bin
# ln -s /usr/local/screen/screen screen

$ screen
```

### MODサーバ、MODのインストール

#### Fabricインストール

公式サイト([install [Fabric Wiki]](https://fabricmc.net/wiki/install))を参考に

- installer.jarダウンロード

```
# curl https://maven.fabricmc.net/net/fabricmc/fabric-installer/0.7.4/fabric-installer-0.7.4.jar -o fabric-installer-0.7.4.jar
```

- ヘルプ確認

```
# java -jar fabric-installer-0.7.4.jar help
Loading Fabric Installer: 0.7.4
help - Opens this menu
client -dir <install dir> -mcversion <minecraft version, default latest> -loader <loader version, default latest>
server -dir <install dir, default current dir> -mcversion <minecraft version, default latest> -loader <loader version, default latest> -downloadMinecraft
```

- Optionは以下の通り

```
-snapshot Enables the usage of snapshot versions of Minecraft.
-dir Used to select the installation dir, defaults to the current working directory.
-mcversion Used to select the minecraft version, defaults to the latest stable version.
-loader Used to select the loader version, defaults to the latest.
-downloadMinecraft Used to automatically download the Minecraft server jar
-noprofile Skip creating client profile
-mavenurl (advanced) Use a custom maven url when installing
-metaurl (advanced) Use a custom meta server url
```
java -jar fabric-installer.jar server コマンドでインストールできるみたい
server -dir "/home/minecraft" って感じでインストールディレクトリ指定できるみたい
-downloadMinecraftはバニラのserver.jarもDLするみたい
-mcversion : インストールするMinecraftサーバのバージョンを指定
指定しないと最新(1.17.1)になってしまうので、今回は1.17を指定する

- インストール実行

```
# java -jar fabric-installer-0.7.4.jar server -mcversion 1.17 -downloadMinecraft
Loading Fabric Installer: 0.7.4
Using latest loader version
Installing Fabric Loader 0.11.6(1.17) on the server
Downloading required files
Downloading library net.fabricmc:tiny-mappings-parser:0.2.2.14
...
...
Done, start server by running fabric-server-launch.jar
Downloading Minecraft server
Done

# ls
fabric-installer-0.7.4.jar  fabric-server-launch.jar  server.jar
```

- 初回実行

```
# java -jar -Xms6G -Xmx10G fabric-server-launch.jar nogui
```

↓ファイルが作成されて、EULA同意してねっていう警告が出る

```
# ll
total 47900
drwxr-xr-x. 2 root root        6 Jul 10 06:52 config
-rw-r--r--. 1 root root      181 Jul 10 06:52 eula.txt
-rw-r--r--. 1 root root   132959 Jul 10 06:38 fabric-installer-0.7.4.jar
-rw-r--r--. 1 root root       51 Jul 10 06:52 fabric-server-launcher.properties
-rw-r--r--. 1 root root  5269476 Jul 10 06:50 fabric-server-launch.jar
drwxr-xr-x. 2 root root       24 Jul 10 06:52 logs
drwxr-xr-x. 2 root root        6 Jul 10 06:52 mods
-rw-r--r--. 1 root root 43626592 Jul 10 06:44 server.jar
-rw-r--r--. 1 root root     1039 Jul 10 06:53 server.properties
```

- End User Lisence Agreement に同意

```
$ sed -i -e 's/false/true/g' eula.txt
```

- いったん起動して入ってみる

```
# java -jar -Xms6G -Xmx10G fabric-server-launch.jar nogui
[07:04:26] [main/INFO]: Loading for game Minecraft 1.17
[07:04:26] [main/INFO]: [FabricLoader] Loading 3 mods:
        - fabricloader@0.11.6
        - java@16
        - minecraft@1.17
[07:04:26] [main/INFO]: SpongePowered MIXIN Subsystem Version=0.8.2 Source=file:/home/minecraft/fabric-server-launch.jar Service=Knot/Fabric Env=SERVER
...
...
[07:05:31] [Worker-Main-5/INFO]: Preparing spawn area: 90%
[07:05:31] [Server thread/INFO]: Time elapsed: 42580 ms
[07:05:31] [Server thread/INFO]: Done (51.592s)! For help, type "help"
[07:05:46] [User Authenticator #1/INFO]: UUID of player c0ba1t_coke is 8fe2893f-e45a-45c5-9889-2e2249a37b7b
[07:05:46] [Server thread/INFO]: c0ba1t_coke[/157.107.66.89:58914] logged in with entity id 417 at (159.5, 68.0, 113.5)
[07:05:46] [Server thread/INFO]: c0ba1t_coke joined the game
[07:06:00] [Server thread/INFO]: c0ba1t_coke lost connection: Disconnected
[07:06:00] [Server thread/INFO]: c0ba1t_coke left the game
```

入れた！

#### Fabric API インストール

[FabricAPIのgithub](https://github.com/FabricMC/fabric)にソースがおいてあるので、これをmodsディレクトリに入れる

README.md に GitHub Releases へのリンクがあるので、これをクリックしてソースのDLページに行く

```md:README.md
# Using Fabric API to play with mods
Make sure you have install fabric loader first. More information about installing Fabric Loader can be found here.

To use Fabric API, download it from CurseForge, [GitHub Releases](https://github.com/FabricMC/fabric/releases) or Modrinth.

The downloaded jar file should be placed in your mods folder.
```

- [1.17]fabricapi0.36.0をDL

```
# cd /home/minecraft/mods
# wget https://github.com/FabricMC/fabric/releases/download/0.36.0%2B1.17/fabric-api-0.36.0+1.17.jar
```

これだけでインストール完了のはず

#### Optifineインストール

##### Optifabric & Optifine インストール

OptifineをFabricと連携して動かすにはOptifabricというやつがいるらしい
どっちもmodsディレクトリにぶち込むだけでOK

- Cloud Storageに保存

wgetとかcurlでインストールできなさそうなんで、
ローカルPCにDLしてから、それをCloud Storageにアップする

コンソールで実施
  - Cloud Storage → [ブラウズ]
  - 保存するバケット名を選択
  - [ファイルをアップロード]をクリック
  - optifabric-1.11.9.jar , preview_OptiFine_1.17_HD_G9_pre26.jar をアップロード

- アップロードした.jarファイルをDL

```
# cd /home/minecraft/mods

# gsutil ls gs://[bucket-name]
gs://[bucket-name]/optifabric-1.11.9.jar
gs://[bucket-name]/preview_OptiFine_1.17_HD_G9_pre26.jar

# gsutil cp gs://[bucket-name]/optifabric-1.11.9.jar ./
Copying gs://[bucket-name]/optifabric-1.11.9.jar...
/ [1 files][374.2 KiB/374.2 KiB]                                                
Operation completed over 1 objects/374.2 KiB.                                    

# gsutil cp gs://[bucket-name]/preview_OptiFine_1.17.1_HD_G9_pre26.jar ./
Copying gs://[bucket-name]/preview_OptiFine_1.17_HD_U_G9_pre26.jar...
/ [1 files][  6.0 MiB/  6.0 MiB]                                                
Operation completed over 1 objects/6.0 MiB.                                      

# ls
fabric-api-0.36.1+1.17.jar  optifabric-1.11.9.jar  preview_OptiFine_1.17_HD_U_G9_pre26.jar
```

## 確認

```
# java -jar -Xms6G -Xmx10G fabric-server-launch.jar nogui
[08:22:47] [main/INFO]: Loading for game Minecraft 1.17
[08:22:47] [ForkJoinPool-1-worker-3/WARN]: Non-Fabric mod JAR at "/home/minecraft/mods/preview_OptiFine_1.17_HD_U_G9_pre26.jar", ignoring
[08:22:47] [main/INFO]: [FabricLoader] Loading 49 mods:
        - fabric@0.36.0+1.17
        - fabric-api-base@0.3.0+a02b44633d
...
...
[08:23:21] [Worker-Main-6/INFO]: Preparing spawn area: 88%
[08:23:22] [Worker-Main-5/INFO]: Preparing spawn area: 91%
[08:23:22] [Worker-Main-4/INFO]: Preparing spawn area: 92%
[08:23:23] [Worker-Main-4/INFO]: Preparing spawn area: 94%
[08:23:23] [Worker-Main-6/INFO]: Preparing spawn area: 98%
[08:23:24] [Server thread/INFO]: Time elapsed: 20068 ms
[08:23:24] [Server thread/INFO]: Done (20.282s)! For help, type "help"
[08:23:58] [User Authenticator #1/INFO]: UUID of player c0ba1t_coke is 8fe2893f-e45a-45c5-9889-2e2249a37b7b
[08:23:59] [Server thread/INFO]: c0ba1t_coke[/157.107.66.89:52072] logged in with entity id 291 at (-148.8212634465673, 72.0, 75.84669863105151)
[08:23:59] [Server thread/INFO]: c0ba1t_coke joined the game
[08:24:02] [Server thread/INFO]: c0ba1t_coke lost connection: Disconnected
[08:24:02] [Server thread/INFO]: c0ba1t_coke left the game
```

入れた！
設定見ても、Optifineの項目が増えてる！

## (おまけ)インスタンス設定修正

### スクリプト修正

startup-scriptとbackup-scriptを[前回のサーバ(1.17バニラ)](https://qiita.com/c0ba1t_coke/items/4312d346fdf3322c5fc9)のものと分けたいので、  
スクリプト修正して置きなおす

```
# cat startup-fabric-mcs.sh 
#!/bin/bash
(crontab -l | grep -v -F "/home/minecraft/backup-fabric.sh" ; echo "0 */1 * * * /home/minecraft/backup-fabric.sh")| crontab -
cd /home/minecraft
screen -d -m -S mcs java -jar -Xms6G -Xmx10G fabric-server-launch.jar nogui
```

```
# cat backup-fabric.sh 
#!/bin/bash
screen -r mcs -X stuff '/save-all\nsave-off\n'
/usr/bin/gsutil cp -R /home/minecraft/world gs://[bucketname-fabric]/$(date "+%Y%m%d-%H%M%S")-world
screen -r mcs -X stuff '/save-on\n'
```
- わかりやすいようにバケットをFabric専用にしておく

- アップロード

```
# gsutil cp startup-fabric-mcs.sh gs://[bucket-name]/
# gsutil cp backup-fabric.sh gs://[bucket-name]/
```

### Terraform 修正

```
  # google_compute_instance.minecraft-mod-server will be updated in-place
  ~ resource "google_compute_instance" "minecraft-mod-server" {
        id                   = "projects/gaming-265014/zones/asia-northeast1-c/instances/mcs02"
      ~ metadata             = {
          ~ "shutdown-script-url" = "gs://[bucket-name]/backup.sh" -> "gs://[bucket-name]/backup-fabric.sh"
          ~ "startup-script-url"  = "gs://[bucket-name]/startup-mcs.sh" -> "gs://[bucket-name]/startup-fabric-mcs.sh"
```
- スクリプトをそれぞれfabric用のを読み込むように変更

## 再起動して自動起動確認

- Storageにバックアップが作成されてるのでよさそう
- Minecraftで接続もできる！


# 完走した感想

Optifineは1.17.1まで対応してるのにOptiFabricが1.17でやり直し食らってクソクソのクソ
今までMODサーバはローカルWindowsでしか立てたことなかったけど、
Linuxでもちゃんと立てれて良かった。(一部力技やったが、、)

Fabric,Optifineのアプデ対応がめっちゃ早いから、今後はバニラやらなくていいかも！？