GoogleDriveでMinecraftサーバーを管理しよう!!!!
前書き
マイクラサーバー記事の第四弾です。
是非、前回までの記事もご覧ください!
第一弾『Raspberry PiでMinecraftサーバーを構築しよう!』
第二弾『DiscordBotでMinecraftサーバーを動かそう!!』
第三弾『統合版でJava版Minecraftサーバーにログインしよう!!!』
前回サーバーを構築した際にはOSを誤って壊してしまい、OSごと初期化しないといけない様な事態になってしまいました💥💥💥
新しく構築しても前回までのワールドは残っておらず、新規でスタートする形になりました。
が、いかんせんプレイ人口は伸びません😢マイクラ自体に流行り廃りの波があるので実はあまり関係はないのでは???とか思ってないけどね!!
なので今回はGoogleDriveにワールドデータをバックアップすることで、前回の様な事故があってもワールドを復活出来る様にします✨久しぶりに記事を書くのでノリが分からん!!こんな感じだったか???
他にもちょこちょこ機能追加していきます!
ということで今回も見切り発車でやっていこ~~🚂=3ポッポー
用意する物
・Minecraftサーバーを起動できるRaspberry Pi
・PC(私はwin10)
・時間(できるだけたくさん)
ファイルのUpping to the date!!
サーバーのバージョンを上げるために、毎回公式サイトからダウンロードして名前変えて……っていうのがめんどくさかったので、自動化させました。
というか前回色々したついでに作ってました。こういう自動化とかがプログラムの楽しいとこですよね!!!ね!!!!papermc、geysermc、floodgateの3つをアップデートできるようにしていきますよ~😊
まずはpapermcから行きましょう。というかここが鬼門過ぎかも……。
アップデートするファイルはmcserver/server.jarで、ダウンロード先は以下URL。
ダウンロードのするURLの形は以下のようになっています。
ここで大切なのはバージョンの番号(1.19.2#263)です!
新しいサーバーファイルが更新されたらこの番号だけ変更されていくので、しっかり対応していくためのプログラムが以下です。
#!/bin/bash
IFS=$'\n'
cd ~/mcserver
for ((i=0; i<4; i++)); do
version=(`cat version.txt`)
version[i]=$((version[i]+1))
for ((j=i+1; j<4; j++)); do
version[j]=0
done
versions=${version[0]}.${version[1]}
if ((version[2]!=0)); then
versions=$versions.${version[2]}
fi
number=${version[3]}
paper_url='https://api.papermc.io/v2/projects/paper/versions/$versions/builds/$number/downloads/paper-$versions-$number.jar'
eval wget $paper_url
if [ $? == 0 ]; then
mv paper-$versions-$number.jar server.jar
cat > version.txt << EOF
${version[0]}
${version[1]}
${version[2]}
${version[3]}
EOF
let "i--"
fi
done
こいつの名前はupdate.shとでもしておいてます。mcserverフォルダに入れておきましょう。
中身を簡単に説明すると、version.txtからバージョン番号を取得し、現在のバージョン+1をそれぞれの番号で調べ、それがダウンロードできた際にserver.jarに上書きし、version.txtにもバージョン番号を上書きする。
といったプログラムになっています。わかりにくっ!
version.txtは現在のバージョン番号が改行で分けられたもので、以下例。
1
19
2
263
まあとりあえずこれを実行するとsever.jarは最新版に更新されるってわけですよ……。へへ…….。
次に統合版のgeysermc、floodgateをアップデートしていくゥ!
こちらは最新版のURLが同じなので簡単でした。
以下をupdate.shに追記していきます。
cd ~/mcserver/plugins
geyser_url='https://ci.opencollab.dev//job/GeyserMC/job/Geyser/job/master/lastSuccessfulBuild/artifact/bootstrap/spigot/build/libs/Geyser-Spigot.jar'
floodgate_url='https://ci.opencollab.dev//job/GeyserMC/job/Floodgate/job/master/lastSuccessfulBuild/artifact/spigot/build/libs/floodgate-spigot.jar'
eval wget $geyser_url
eval wget $floodgate_url
mv Geyser-Spigot.jar.1 Geyser-Spigot.jar
mv floodgate-spigot.jar.1 floodgate-spigot.jar
こっちの方がわかりやすいですね~~全部こうしてくれよ!こちらは同じ名前でファイルが入ってしまうので、ファイル名に付く.1を取り除くこと(上書き保存)が必要です。
update.shを実行するために以下も作成していきまちゅ。
[Unit]
Description=Jar Update
After=network.target
[Service]
Type=forking
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/mcserver/
ExecStart=/home/ubuntu/mcserver/update.sh
Restart=simple
[Install]
WantedBy=multi-user.target
こいつを/etc/systemd/system/jar.serviceとする。
起動時にupdate.shを実行するようにしましたが、一応サーバー起動と被ると怖いので、DiscordBotがjar.serviceの後に実行されるように、以下のようにdis.serviceも変更しておきます。
[Unit]
Description=Discord Bot
After=jar.service
[Service]
Type=forking
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/mcserver/
ExecStart=/home/ubuntu/mcserver/distart.sh
Restart=always
[Install]
WantedBy=multi-user.target
Afterの欄でスね。
あとは以下で、実行権限とか.serviceファイルの更新もしてあげましょうね。
chmod +x ~/mcserver/update.sh
sudo systemctl daemon-reload
そしたら再起動で、多分適応されると思われます。
これで毎回なんじゃかんじゃしなくて済みます。
ほんとはサイトが更新されたらとかやろうと思ってました。が、めんどくさかったので止めました。jar.serviceで我慢してやりますか……!
注意点としてたまに連番じゃない時があるので、自分でversion.txtを編集する必要があるっていうのと、version.txtを編集する際は最新の番号から1つ前の番号を保存する必要があります。(プログラムの性質上)
以下以下うるせー文章を見て頂きありがとうございます!
残念ながらここから本編です!!
データのBack to the up!!!
準備のための準備のための準備のための……
じゃあ早速ソフトを入れよう!としたんですが、ubuntu21.10からアップデートを行わないといけないようなので、やっちゃいます(笑)
最新のubuntu22.04にアップデートしていきます。
とりあえずsudo do-release-upgradeでアップデート!と思いきや、apt updateしてください!!って怒られました……
そんでapt updateやったらエラー!エラー!!!
なんか/etc/apt/sources.listがports.ubuntu.com/ubuntu-portsとかいう20.10の古いやつだからダメ!みたいなことになってるっぽいので以下で書き換えていきます。
sed -i -e 's/ports.ubuntu.com\/ubuntu-ports/old-releases.ubuntu.com\/ubuntu/g' /etc/apt/sources.list
やっとこapt updateできるようになったので以下以下。
sudo apt update
sudo apt upgrade
sudo do-release-upgrade
進んでいく中でcontinue?って言われたらy押して、please press [Enter]って言われたらEnter押しましょう。
軽い気持ちで始めたら結構時間かかってビビりました。
多分2時間くらいかかりますので、時間があるときにやりましょう。僕は時間ないときにやったので最悪でした。後から気づきましたが勢い余ってUbuntu22.10にアップデートしてました。
ダウングレードはできませんが22.04のものを入れて対応していきます。
これでうまくいくと思いきや、次はosをアップデートしたことでdiscordbotが起動しなくなったので、discord.pyの更新も行った。なんなら半分作り直した……。以下でdiscord.pyも最新版に!
pip3 install discord.py
最新版だとなんだか書き方全然違うみたいなので、いろいろ調べてなんとか兆しが見えてきたら午前3時😊😊😊😊明日は遅刻かな😊😊😊😊😊ということで
p.s.何とか遅刻5分前に間に合いました(もう夜更かししません許して……。)遅刻を乗り越えたので、以下イカ!!!
import discord
from discord.ext import commands
import os
import time
TOKEN = 'Jibunn0T0KENw0Iremash0u'
bot = commands.Bot(command_prefix = '!', intents = discord.Intents.all())
@bot.event
async def on_ready():
print('ログインしました')
@bot.command()
async def command(ctx):
file = open('command.txt', 'r')
txt = file.read()
await ctx.send(txt)
file.close()
@bot.command()
async def start(ctx):
if os.system('systemctl is-active ms') == 0:
await ctx.send('Server - OPEN')
else :
await ctx.send('wait a minute...')
os.system('sudo systemctl start ms')
time.sleep(120)
await ctx.send('Server - OPEN')
@bot.command()
async def stop(ctx):
if os.system('systemctl is-active ms') == 0:
await ctx.send('wait a minute...')
os.system('sudo systemctl stop ms')
time.sleep(90)
await ctx.send('Server - CLOSE')
else :
await ctx.send('Server - CLOSE')
@bot.command()
async def save(ctx):
if os.system('systemctl is-active ms') == 0:
os.system('sudo systemctl start ms-save.service')
await ctx.send('world saved.')
else :
await ctx.send('Server - CLOSE')
@bot.command()
async def status(ctx):
if os.system('systemctl is-active ms') == 0:
await ctx.send('Server - OPEN')
else :
await ctx.send('Server - CLOSE')
bot.run(TOKEN)
mcserver/msdis.pyの内容は処理層に変更はほとんどありませんが、discord.ext.commandsを入れてコマンドを管理するようになりました。
他にもちょこちょこ変更していきます。
[Unit]
Description=Discord Bot
After=jar.service
[Service]
Type=forking
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/mcserver/
ExecStart=/home/ubuntu/mcserver/distart.sh
Restart=simple
[Install]
WantedBy=multi-user.target
/etc/systemd/system/dis.serviceのRestart=simpleへ変更。
#!/bin/sh
screen -UAmdS Discord python3 /home/ubuntu/mcserver/msdis.py
mcserver/distart.shの実行権限をsudoからユーザーへ変更。
(これはファイルの作成方法による可能性大なので、変える必要がない場合もありそう。)
こんな感じで何とか戻りました……。
ただアップデートするだけだと思ったら、全体的にアップデートしなくちゃいけなくて大変……。
目についていないだけでアップデートが必要な箇所もありそうですが、見つかったら都度対応します……。
バックアップ・ルックバック・バックパック・キックバック
ということでほんへと言っても過言ではないワールドのバックアップを実装していく~~~!!!やっとか。
ほんじゃまず以下でソフトを入れてくぞ!!
それなりに時間かかりますので、気を付けて!
sudo dpkg --configure -a
sudo apt install software-properties-common dirmngr
sudo add-apt-repository ppa:alessandro-strada/ppa
よーく見るとここでports.ubuntu.comが入っていますね。
ここまでの努力の賜物を感じます。
どんどんいくじょ!!
sudo nano /etc/apt/sources.list.d/alessandro-strada-ubuntu-ppa-jammy.list
中身は以下に変更!
deb https://ppa.launchpadcontent.net/alessandro-strada/ppa/ubuntu/ jammy main
#deb-src https://ppa.launchpadcontent.net/alessandro-strada/ppa/ubuntu/ jammy main
以下!以下!!
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys AD5F235DF639B041
apt update
apt install google-drive-ocamlfuse
これでエラーなければ入ったと思います。
osアップデートからソフト入れるまでにリアル3日かかりました……。
次はGoogle Driveにバックアップを取る際の、Googleのアカウントをつくってこい!話はそれからだ!!
ここからの操作はPCでやりましょう。
そのアカウントで以下のURLにアクセスして設定していきます。
設定項目を箇条書きで書いてまいります。
設定割と沢山ありますね~。
入力欄は編集して頂いても大丈夫です。
しっかり自分のメールアドレスを入力しましょうね。
またラズパイに戻ります。
以下っちょ!
google-drive-ocamlfuse -headless -id クライアントID -secret クライアントシークレット
先程コピーしたクライアントIDとクライアントシークレットを入れてくだちい。
そうすると以下が出力されます。
Please, open the following URL in a web browser: https://accounts.google.com/o/oauth2/auth?client_id=...
Please enter the verification code:
一行目の発行されたURLを踏んで、進めていきます。
この時先程、登録したメールアドレスでログインしていることが必要です。
許可を選択すると認証コードが発行されるので、二行目にコードを張り付けて実行します。
mkdir ~/gdrive
google-drive-ocamlfuse ~/gdrive
GoogleDrive用のフォルダを用意してマウントしてあげると、GoogleDriveと接続されます。
このフォルダを介してデータのやり取りをすることが出来ます!!!
出来てよかった……!!
google-drive-ocamlfuse ~/gdrive
色々いじってて気が付いたんですが、再起動するとフォルダのマウントが初期化してしまうので、.bashrcに↑のコマンドを追記します。
ドライブに保存するシェル書いてくぞ!
とりあえず全てがぶっ壊れたとき用に、最初は全部保存してもいいかなと思います。
後はワールドデータを継続的に保存していきます。
まずはバックアップ用のフォルダを作成します。
mkdir ~/gdrive/backup
backupフォルダに月ごとに分けて入れていきます。
必要なフォルダとファイルは全7個ってことにしておきます。
イカ。
#!/bin/bash
year=`date '+%y'`
month=`date '+%m'`
year_month=$year.$month
delete_year_month=$((year-1)).$month
~/mcserver/distop.sh
~/mcserver/stop.sh
mkdir ~/gdrive/backup/$year_month
mkdir ~/gdrive/backup/$year_month/plugins
cp ~/mcserver/world ~/gdrive/backup/$year_month -r
cp ~/mcserver/world_nether ~/gdrive/backup/$year_month -r
cp ~/mcserver/world_the_end ~/gdrive/backup/$year_month -r
cp ~/mcserver/server.jar ~/gdrive/backup/$year_month -r
cp ~/mcserver/plugins/Geyser-Spigot.jar ~/gdrive/backup/$year_month/plugins -r
cp ~/mcserver/plugins/floodgate-spigot.jar ~/gdrive/backup/$year_month/plugins -r
cp ~/mcserver/version.txt ~/gdrive/backup/$year_month -r
rm ~/gdrive/backup/$delete_year_month -r
sudo reboot
mcserver/backup.shとして保存します。
上三つのフォルダはワールドデータで、中三つのファイルは起動用jarで、下一つのファイルはバージョンのテキストです。
バックアップの際は、サーバーを起動しているとデータが破損する可能性があるのでサーバーを落とし、バックアップ作成中にサーバーを起動できないようにdiscordbotを切断しましょう。
ドライブに無限にデータが入るわけではないので、1年前のバックアップは消すようにします。
バックアップは取れましたと……。
毎月末に実行するため、以下をcrontabに追記します。
0 15 28-31 * * /usr/bin/test $(date -d '+1 day' +%d) -eq 1 && bash ~/mcserver/backup.sh
月末の日本時間で0時にバックアップをします。
じゃあ逆にリストア(復元)するためのシェルも作りますか……。もうちゅかれた……。はいはい、いかいか。
#!/bin/bash
read -p "backup directory name:" year_month
if [ ! -d ~/gdrive/backup/$year_month ]; then
echo $year_month directory does not exist.
fi
if [ -d ~/gdrive/backup/$year_month ]; then
backup_file=before_restore
~/mcserver/distop.sh
~/mcserver/stop.sh
if [ $backup_file != $year_month ]; then
echo backup
cp ~/mcserver/world ~/gdrive/backup/$backup_file -r
cp ~/mcserver/world_nether ~/gdrive/backup/$backup_file -r
cp ~/mcserver/world_the_end ~/gdrive/backup/$backup_file -r
cp ~/mcserver/server.jar ~/gdrive/backup/$backup_file -r
cp ~/mcserver/plugins/Geyser-Spigot.jar ~/gdrive/backup/$backup_file/plugins -r
cp ~/mcserver/plugins/floodgate-spigot.jar ~/gdrive/backup/$backup_file/plugins -r
cp ~/mcserver/version.txt ~/gdrive/backup/$backup_file -r
fi
echo restore
cp ~/gdrive/backup/$year_month/world ~/mcserver -r
cp ~/gdrive/backup/$year_month/world_nether ~/mcserver -r
cp ~/gdrive/backup/$year_month/world_the_end ~/mcserver -r
cp ~/gdrive/backup/$year_month/server.jar ~/mcserver -r
cp ~/gdrive/backup/$year_month/plugins/Geyser-Spigot.jar ~/mcserver/plugins -r
cp ~/gdrive/backup/$year_month/plugins/floodgate-spigot.jar ~/mcserver/plugins -r
cp ~/gdrive/backup/$year_month/version.txt ~/mcserver -r
sudo reboot
fi
mcserver/restore.shとして保存していく。
backupファイルに入っているフォルダ名を入力することで、直前のフォルダをバックアップして、指定したフォルダにあるデータをmcserverに呼び出せるってわけですな。
こいつを使うために直前バックアップ用のフォルダを作成しておきます。
mkdir ~/gdrive/backup/before_restore
mkdir ~/gdrive/backup/before_restore/plugins
バックアップを取ってからリストアするので、かなり時間がかかります。
大体1時間くらいかかりました。
自動再起動を入れている方は、リストアする時間に気を付けて行いましょう。
実際にバックアップとリストアを試してみよう!!
バックアップを取るデータがイカの画像になります。
バックアップ後のデータが以下です。
リストア後のワールドが以下です。
今回はこの辺にしといてやるわ!!!じゃあな!!!!ま~じで疲れたんでこの辺で許してやってください……。
後書き
実はラズパイの消費電力を減らす長期運用設定とやらもしようと思っていたのですが、知識不足で実装に至りませんでした。くやしーー!!
HDMIやWifiの無線、Bluetooth等を切ることができるようです。あまり設定方法がわからなかったし、調べると消費電力がそもそも少ないから別にやらなくても大丈夫そうなので、実装予定ないです。
一つここで注意喚起をしておくと、私はアホなのでSSHで外部から接続中にrebootではなくshutdownコマンドで落としてしまいました。アホなので。
皆さんはこのようなことがないよう日頃からrebootコマンドを使用しましょうね……。
というか今回実装するまでの時間が長すぎ!!!!
マジで1週間暇さえあればいじって、やっとこ終わったことにしました……。
正直プログラムはだいぶ雑に書いているので、納得いってないところがおおいです。
もっといじるべきところもたくさんありますが、放っておいてもなんか動いてるのでとりあえずよしってことで。
一応最初に思い描いていた部分まで実装が終わったので、次回の記事はこれまでのまとめというか整理したものを出します。
総集編ってやつです。手癖で書いてるからファイル名や変数名等がわかり肉すぎる。
なんだかんだで改良も加えると思うので、次回もぜひ見てくれよな!!