【GCP】在GCE上搭建Java版Minecraft服务器【Java版Minecraft】
总结
第三个解决GCP上构建的集成版Minecraft服务器问题。
这次我们要将服务器从Minecraft的整合版转换为Java版。
的目的
- 前回までに構築していた統合版Minecraftサーバーを、Java版に変更する。
预先调查
プラグイン対応について
いろいろ試したが、統合版では現状いろいろ無理…という結論になった。
PMMP:起動、複数ワールド管理は出来たが、mobが沸かない。PureEntitiesX のPM4対応待ち?
LiteLoaderBDS:wine併用がめんどくさい、ドキュメントが中国語でわからん……。
BDSX:起動までは出来たが、プラグインの入れ方がわからんというか、npmで入れるのはわかるんだが、複数ワールドを管理するようなプラグインが見つからなかった。
Java版Minecraftサーバー
プラグインやmodはJava版の方が充実しており、mobのスポーンや、統合版クライアントからの接続も実用レベルっぽかったので、ダメ元でこちらを構築してみることにする。
これも統合版と同じくというか、それ以上に様々な種類の非公式サーバーが存在するのだが、老舗でプラグイン数も多い「Spigot」をまずは試してみる。
公式サイトは下記。
SpigotMC – High Performance Minecraft
1. 建立
将已构建的Minecraft集成服务器(官方版)替换为Spigot。
1.1. 代码修正
Minecraft服务器的建立是通过cloud-init(cloud-config)来实施的,因此需要对其进行修正。
#cloud-config
timezone: 亚洲/东京
locale: ja_JP.utf8
packages:
– openjdk-17-jre-headless
– expect
– apache2
– unzip
– zip
users:
– name: ‘minecraft’
plain_text_passwd: ‘minecraft’
shell: ‘/bin/bash’
sudo: ‘ALL=(ALL) NOPASSWD:ALL’
lock_passwd: false
runcmd:
– mkdir /opt/minecraft
– mkdir /opt/minecraft/backup_worlds
– mv /home/minecraft/mcs_backup.sh /opt/minecraft/mcs_backup.sh
– mv /home/minecraft/spigot_init.sh /opt/minecraft/spigot_init.sh
write_files:
– path: /home/minecraft/mcs_backup.sh
content: |
#!/bin/bash
screen -r tskserver -X stuff ‘/save-all\n/save-off\n’
WORLDS=(hoge)
BACKUP_BUCKET=’gs://hoge/’
for world in ${WORLDS[@]}; do
cp -r ${BASH_SOURCE%/*}/${world} ${BASH_SOURCE%/*}/backup_worlds/
done
/usr/bin/zip -r ${BASH_SOURCE%/*}/backup_worlds.zip ${BASH_SOURCE%/*}/backup_worlds
/snap/bin/gsutil cp -R ${BASH_SOURCE%/*}/backup_worlds.zip ${BACKUP_BUCKET}
/bin/rm ${BASH_SOURCE%/*}/backup_worlds.zip
screen -r tskserver -X stuff ‘/save-on\n’
permissions: ‘0755’
owner: root:root
– path: /home/minecraft/spigot_init.sh
content: |
#!/bin/bash
# おまじない
cd `dirname $0`
# 必要ファイルをDL
wget -P /opt/minecraft https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
wget -P /opt/minecraft/plugins https://ci.lucko.me/job/LuckPerms/1429/artifact/bukkit/loader/build/libs/LuckPerms-Bukkit-5.4.21.jar
wget –trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/dynmap/files/latest
wget –trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/worldedit/files/latest
wget –trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/WorldGuard/files/latest
wget –trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/Multiverse-Core/files/latest
wget –trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/Multiverse-Portals/files/latest
wget –trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/multiverse-inventories/files/latest
wget –trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/Multiverse-NetherPortals/files/latest
wget -P /opt/minecraft/plugins https://ci.opencollab.dev//job/GeyserMC/job/Geyser/job/master/lastSuccessfulBuild/artifact/bootstrap/spigot/target/Geyser-Spigot.jar
wget -P /opt/minecraft/plugins https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/master/lastSuccessfulBuild/artifact/spigot/target/floodgate-spigot.jar
wget -P /opt/minecraft/plugins https://github.com/Camotoy/GeyserSkinManager/releases/download/1.6/GeyserSkinManager-Spigot.jar
wget -P /opt/minecraft/plugins https://ci.viaversion.com/job/ViaVersion/lastBuild/artifact/build/libs/ViaVersion-4.2.2-SNAPSHOT.jar
wget -P /opt/minecraft/plugins https://ci.viaversion.com/view/ViaBackwards/job/ViaBackwards/lastBuild/artifact/build/libs/ViaBackwards-4.2.1.jar
wget -P /opt/minecraft/plugins https://ci.viaversion.com/view/ViaRewind/job/ViaRewind/lastBuild/artifact/all/target/ViaRewind-2.0.3-SNAPSHOT.jar
# ビルド
while [ ! -e BuildTools.jar ] ; do sleep 10; done && java -jar BuildTools.jar –rev latest
# ビルド終了まで待つ
while [ ! -e spigot-* ] ; do sleep 10; done
# metadata_startup_script の起動を簡易化する(バージョンに依存させない)ためにリネーム(コピー)
ver_num=`ls | grep spigot- | cut -c 8- | rev | cut -c 5- | rev`
cp spigot-${ver_num}.jar spigot.jar
# 初回起動
java -Xms1024M -Xmx8G -jar spigot.jar nogui
# eula 同意、server.properties 変更
sed -i”.org” -e “s/^online-mode=true$/online-mode=false/g” /opt/minecraft/server.properties
sed -i -e “s/level-name=world$/level-name=lobby/g” /opt/minecraft/server.properties
sed -i -e “s/server-port=25565$/server-port=19132/g” /opt/minecraft/server.properties
sed -i -e ‘$ a server_name=”hoge”‘ /opt/minecraft/server.properties
sed -i”.org” -e “s/eula=false$/eula=true/g” /opt/minecraft/eula.txt
# 2回目起動
java -Xms1024M -Xmx8G -jar spigot.jar nogui
# プラグインの設定変更
sed -i”.org” -e “s/clone-remote-port: false$/clone-remote-port: true/g” /opt/minecraft/plugins/Geyser-Spigot/config.yml
sed -i -e “s/auth-type: online$/auth-type: floodgate/g” /opt/minecraft/plugins/Geyser-Spigot/config.yml
sed -i -e ‘s/server-name: “Geyser”$/server-name: “hoge”/g’ /opt/minecraft/plugins/Geyser-Spigot/config.yml
sed -i -e “s/passthrough-motd: false$/passthrough-motd: true/g” /opt/minecraft/plugins/Geyser-Spigot/config.yml
sed -i -e “s/passthrough-player-counts: false$/passthrough-player-counts: true/g” /opt/minecraft/plugins/Geyser-Spigot/config.yml
# サーバー再起動
reboot
permissions: ‘0755’
owner: root:root
– path: /var/www/html/index.html
content: |
<!doctype html>
permissions: ‘0644’
owner: root:root
# reboot
#power_state:
# delay: “+15”
# mode: reboot
由于结构发生了巨大的变化,我们将每个区块进行解释(或者说备注)如下所示,runcmd: 。
runcmd:
- mkdir /opt/minecraft
- mkdir /opt/minecraft/backup_worlds
- mv /home/minecraft/mcs_backup.sh /opt/minecraft/mcs_backup.sh
- mv /home/minecraft/spigot_init.sh /opt/minecraft/spigot_init.sh
由于数量增加和特殊符号转义太麻烦,我将其脚本化。
在“spigot_init.sh”中,我们进行了服务器程序、插件和各种设置的下载以及其他各种操作。
“mcs_backup.sh”是一个通常用来将世界数据备份到GCS的脚本,但由于更改了服务器程序,目录结构也有所变化,因此我们进行了一些修改(详细信息请参考后述)。
脚本的内容记录在write_files:中,rumcmd:仅包括必要的最基本的目录创建和脚本文件移动操作。
以下是备份脚本。
- path: /home/minecraft/mcs_backup.sh
content: |
#!/bin/bash
screen -r tskserver -X stuff '/save-all\n/save-off\n'
WORLDS=(hoge)
BACKUP_BUCKET='gs://hoge/'
for world in ${WORLDS[@]}; do
cp -r ${BASH_SOURCE%/*}/${world} ${BASH_SOURCE%/*}/backup_worlds/
done
/usr/bin/zip -r ${BASH_SOURCE%/*}/backup_worlds.zip ${BASH_SOURCE%/*}/backup_worlds
/snap/bin/gsutil cp -R ${BASH_SOURCE%/*}/backup_worlds.zip ${BACKUP_BUCKET}
/bin/rm ${BASH_SOURCE%/*}/backup_worlds.zip
screen -r tskserver -X stuff '/save-on\n'
permissions: '0755'
owner: root:root
統合版的世界数据被整合到安装目录内的“worlds”文件夹中,而Java版会在安装目录内创建各个世界的文件夹。
因此,如果要批量备份指定目录,就必须指定安装目录,这会导致包含大量多余文件。
为了解决这个问题,我添加了将每个世界文件夹暂时复制到备份目录的步骤。
由于只有在创建世界后才知道世界名称,所以手动维护的部分也增加了……。
我曾考虑过在世界名称(文件夹名称)上添加前缀(world_)或后缀(_world),但考虑到在游戏内指定世界名称,我不希望过于冗长,所以没有采用。
以下是用于服务器初始设置的脚本。
- path: /home/minecraft/spigot_init.sh
content: |
#!/bin/bash
# おまじない
cd `dirname $0`
# 必要ファイルをDL
wget -P /opt/minecraft https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
wget -P /opt/minecraft/plugins https://ci.lucko.me/job/LuckPerms/1429/artifact/bukkit/loader/build/libs/LuckPerms-Bukkit-5.4.21.jar
wget --trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/dynmap/files/latest
wget --trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/worldedit/files/latest
wget --trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/WorldGuard/files/latest
wget --trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/Multiverse-Core/files/latest
wget --trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/Multiverse-Portals/files/latest
wget --trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/multiverse-inventories/files/latest
wget --trust-server-names -P /opt/minecraft/plugins https://dev.bukkit.org/projects/Multiverse-NetherPortals/files/latest
wget -P /opt/minecraft/plugins https://ci.opencollab.dev//job/GeyserMC/job/Geyser/job/master/lastSuccessfulBuild/artifact/bootstrap/spigot/target/Geyser-Spigot.jar
wget -P /opt/minecraft/plugins https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/master/lastSuccessfulBuild/artifact/spigot/target/floodgate-spigot.jar
wget -P /opt/minecraft/plugins https://github.com/Camotoy/GeyserSkinManager/releases/download/1.6/GeyserSkinManager-Spigot.jar
wget -P /opt/minecraft/plugins https://ci.viaversion.com/job/ViaVersion/lastBuild/artifact/build/libs/ViaVersion-4.2.2-SNAPSHOT.jar
wget -P /opt/minecraft/plugins https://ci.viaversion.com/view/ViaBackwards/job/ViaBackwards/lastBuild/artifact/build/libs/ViaBackwards-4.2.1.jar
wget -P /opt/minecraft/plugins https://ci.viaversion.com/view/ViaRewind/job/ViaRewind/lastBuild/artifact/all/target/ViaRewind-2.0.3-SNAPSHOT.jar
# ビルド
while [ ! -e BuildTools.jar ] ; do sleep 10; done && java -jar BuildTools.jar --rev latest
# ビルド終了まで待つ
while [ ! -e spigot-* ] ; do sleep 10; done
# metadata_startup_script の起動を簡易化する(バージョンに依存させない)ためにリネーム(コピー)
ver_num=`ls | grep spigot- | cut -c 8- | rev | cut -c 5- | rev`
cp spigot-${ver_num}.jar spigot.jar
# 初回起動
java -Xms1024M -Xmx8G -jar spigot.jar nogui
# eula 同意、server.properties 変更
sed -i".org" -e "s/^online-mode=true$/online-mode=false/g" /opt/minecraft/server.properties
sed -i -e "s/level-name=world$/level-name=lobby/g" /opt/minecraft/server.properties
sed -i -e "s/server-port=25565$/server-port=19132/g" /opt/minecraft/server.properties
sed -i -e '$ a server_name="hoge"' /opt/minecraft/server.properties
sed -i".org" -e "s/eula=false$/eula=true/g" /opt/minecraft/eula.txt
# 2回目起動
java -Xms1024M -Xmx8G -jar spigot.jar nogui
# プラグインの設定変更
sed -i".org" -e "s/clone-remote-port: false$/clone-remote-port: true/g" /opt/minecraft/plugins/Geyser-Spigot/config.yml
sed -i -e "s/auth-type: online$/auth-type: floodgate/g" /opt/minecraft/plugins/Geyser-Spigot/config.yml
sed -i -e 's/server-name: "Geyser"$/server-name: "hoge"/g' /opt/minecraft/plugins/Geyser-Spigot/config.yml
sed -i -e "s/passthrough-motd: false$/passthrough-motd: true/g" /opt/minecraft/plugins/Geyser-Spigot/config.yml
sed -i -e "s/passthrough-player-counts: false$/passthrough-player-counts: true/g" /opt/minecraft/plugins/Geyser-Spigot/config.yml
# サーバー再起動
reboot
permissions: '0755'
owner: root:root
這部分很麻煩的是進行 Spigot 的建置所需的「java -jar BuildTools.jar –rev latest」指令。
在 cloud-init 中執行上述腳本時,總是會由於 Java 錯誤而失敗。
嘗試在腳本內進行 JDK 的安裝,明確指定環境變數,利用迴圈等待建置結果的檔案創建,嘗試了很多方法,但都無效…
相同的腳本在正常登入伺服器後執行沒問題,因此決定手動執行本腳本。
另外,生成的可执行文件包含了版本号,在自动化启动和停止方面会造成干扰,因此我加入了一个将文件复制到不包含版本号的文件名的过程(虽然也可以进行重命名,但为了保留原始文件,就仅仅进行了复制)。
以下是Dynmap插件的用途。
- path: /var/www/html/index.html
content: |
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Jump to Dynmap</title>
<meta http-equiv="Refresh" content="0;URL=hoge:8123">
</head>
<body> </body>
</html>
permissions: '0644'
owner: root:root
Dynmap是一个插件,可以在Web浏览器上查看Minecraft游戏内的地图。
因为它看起来很方便和有趣,所以我安装了它。
为了能够通过Web浏览器访问它,需要在端口8123上输入URL,所以我安装了apache,并将80端口重定向到8123端口。
在负载均衡器上接收https流量,或者在Traffic Director上进行路由等,可能还有一些更智能的方式可用,但可能需要额外费用,所以暂时就用这个吧。
另外,还对 metadata_shutdown_script 进行了一些修改。
variable "gce" {
default = {
dev = {
minecraft-game-server = {
machine_type = "e2-standard-4"
image = "ubuntu-os-cloud/ubuntu-1804-lts"
type = "pd-standard"
size = "10"
block-project-ssh-keys = true
key_name = "mcs_key"
deletion_protection = false
metadata_startup_script = "cd /opt/minecraft/\nscreen -dmS tskserver java -Xms1024M -Xmx8G -jar spigot.jar nogui"
metadata_shutdown_script = "cd /opt/minecraft/\nscreen -p 0 -S tskserver -X eval 'stuff 'say 30秒後にサーバーをシャットダウンします、ログアウトしてください\\015'\nsleep 10\nscreen -p 0 -S tskserver -X eval 'stuff 'say 20秒後にサーバーをシャットダウンします、ログアウトしてください\\015'\nsleep 10\nscreen -p 0 -S tskserver -X eval 'stuff 'say 10秒後にサーバーをシャットダウンします、ログアウトしてください\\015'\nsleep 5\nscreen -p 0 -S tskserver -X eval 'stuff 'say 5秒後にサーバーをシャットダウンします、ログアウトしてください\\015'\nsleep 5\nscreen -r tskserver -X stuff 'save-all\\015'\nscreen -r tskserver -X stuff 'stop'\n/opt/minecraft/mcs_backup.sh"
}
}
prd = {
}
}
}
尽管只需大约30秒,但在关闭游戏之前,会进行游戏内的倒计时通知。基本上,最后退出游戏的人会从Discord发送关闭命令,或者根据CPU使用率自动关闭,所以实际上除了自我满足之外,没有其他作用……。我认为,在脚本中能够发送消息到Minecraft游戏内是一个相当有趣的功能。
1.2. 插件
基本上只需要下载和放置,因此在前面的 cloud-init(cloud-config) 中已经执行过了(虽然有些设置需要在首次服务器启动后进行)。但是 cloud-init(cloud-config) 只包含到最终更新文件的链接,所以我将在这里简要介绍一下。
已安裝的插件如下:
LuckPerms-Bukkit-5.4.21(权限管理)
Dynmap® v3.4-beta-3(通过浏览器查看Minecraft地图)
WorldEdit for Bukkit 7.2.10(地图编辑器)
worldguard-bukkit-7.0.7(区域保护等)
Multiverse-Core-4.3.1(多世界管理)
Multiverse-Portals-4.2.1(多世界传送门)
Multiverse-NetherPortals-4.2.2(下界世界管理)
Per World Inventory 2.3.2(多世界物品管理)
GeyserMC(允许连接基岩版客户端)
Floodgate(允许无需认证连接基岩版客户端)
GeyserSkinManager 1.6(应用基岩版皮肤)
ViaVersion 4.2.1(允许连接新的客户端版本)
ViaBackwards 4.2.1(允许连接旧的客户端版本)
ViaRewind 2.0.2(允许连接更旧的客户端版本)
暫時只是把可能需要的東西一個個加進去,所以說實話,我還沒跟上理解。
在玩的同時,我會進行一些調整…
關於每個插件的解說,也許等稍微理解得更多或者心情好的時候,可能會單獨寫或者可能不寫。
1.3. 驗證動作
经过确认,可以顺利登录并在PC版和Switch版之间进行世界转移。
而且mob也能正常生成和移动。
此外,从Discord进行服务器操作,自动停止功能以及世界数据备份等运营方面的功能也都能正常运行。
呼,终于能够开始游玩了,感觉一切准备工作都完成了。
顺便提一下,目前的全球构造如下。
-
- 大堂用世界
-
- 家庭用世界
-
- 公会用世界
- 收集素材用世界
最初登录服务器后,会进入大厅用的世界,然后再通过传送门进入各个世界。暂时将2和3分开是为了方便,但如果互动增多的话,可能会合并成一个。
1.4. 补充
通过将版本更改为Java版和增加世界数量,导致闲置状态下(登录用户为0时)的CPU使用率从1%上升到约7%。
因此,将CPU使用率警报从“低于2%”更改为“低于8%”。
variable "monitoring" {
default = {
dev = {
cpu_utilization_threshold = 0.08
cpu_utilization_threshold_percent = 8
trigger_topic = true
available_memory_mb = 128
timeout = 120
retry = true
entry_point = "run"
}
}