マイクラサーバーの自動停止【Python】

当ページのリンクには広告が含まれています。
code, coding, computer

こんにちは、ふじみやです。

これまでAWSを使ったマイクラサーバーの運用についてご説明をしてきました。

特に、サーバーの開始に関してはかなり簡略化が出来たのではないかと思いますが、サーバーの停止についてはPCのデスクトップやLINEから停止の操作をしなければならず、インスタンスを停止し忘れてしまうこともありえます。

今回はそういったミスでAWSの料金が余分にかかってしまうことが無いように、マイクラサーバーに誰もいない場合にはサーバーの停止スクリプトが実行されるプログラムをPythonで作成する方法をご説明します。

目次

事前準備

今回は、プログラムを作成する前に何点か事前準備が必要となりますのでご対応ください。

Pythonのインストール

お使いのインスタンスにPython3系がインストールされていない方はインストールをしておきましょう。
(本記事ではインストール方法のご紹介は省略させていただきます。)

マイクラサーバーのscreenでの起動とログファイル出力

プログラムを作成する前に、マイクラサーバーをバックグラウンドで立ち上げ、日付ごとにログファイルがちゃんと作成されるようにしておきましょう。

停止スクリプトの作成

上記を設定するとマイクラサーバーがscreenで立ち上がるようになりますが、これをscreenの外部から停止するためのスクリプト(stop.sh)を作成し、minecraftディレクトリ の直下に保存しておきます。

# 停止コマンド発行
screen -r -X eval 'stuff "stop"\015'

プログラムの設計

プログラムの作成に着手する前に、プログラムの手順をまとめておきます。

  1. ログファイル内の「joined」と「left」の数を数える
  2. 「joined」と「left」が同数ならサーバーを停止
  3. 同数でないのであれば何もしない

プログラムの作成

stop.sh と同様に minecraftディレクトリ の直下に auto-stop.py という名称でプログラムを作成します。

ファイルの中身については以下の通りです。

import os
import sys
import datetime
import subprocess

# 今日の日付のログファイルのパスを指定
today = datetime.date.today()
file_path = "/home/ec2-user/minecraft/logs/{}.log".format(today)

# ログファイルが存在しているかを確認
# ファイルが存在しない場合にはプログラムを終了
d = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
is_file = os.path.isfile(file_path)
if is_file:
    pass
else:
    text = "{} No log found".format(d)
    print(text)
    sys.exit()

# 「joined」と「left」のカウント用変数(初期化)
join_cnt = 0
left_cnt = 0

# ログファイルを開き「joined」と「left」の数をそれぞれカウント
with open(file_path) as log_file:
    for line in log_file:
        if "joined" in line:
            join_cnt += 1
        elif "left" in line:
            left_cnt += 1

# 「joined」と「left」が同数の場合には停止スクリプトを実行し1分後にインスタンスを停止
# 同数でない場合には「誰かがログイン中」と表示
if join_cnt == left_cnt:
    subprocess.call(["bash", "-c", "/home/ec2-user/minecraft/stop.sh"])
    subprocess.call(["sudo", "shutdown", "-h", "+1"])
else:
    print("someone is online")

なお、 floodgate プラグインを導入している場合、次の通り統合版のプレイヤーが参加した際に二重で「joined」がカウントされてしまいます。

[18:44:43 INFO]: [floodgate] Floodgate player logged in as <player name> joined (UUID: 00000000-0000-0000-xxxx-xxxxxxxxxxxx) 
[18:44:43 INFO]: <player name> joined the game

ただしくプログラムを動作させるためには行に含まれる文字列を変更してあげましょう。「UUID of player」をキーにすれば正しくカウントできるはずです。

# ログファイルを開き「joined」と「left」の数をそれぞれカウント
with open(file_path) as log_file:
    for line in log_file:
        if "UUID of player" in line:
            join_cnt += 1
        elif "left" in line:
            left_cnt += 1

筆者の環境では上記以外にも少し変更した方法を採用していますので、上記で上手くいかないという方がいらっしゃいましたら お問い合わせ よりご連絡をいただけますと幸いです。

cronへの登録

Pythonのプログラムを作成したら、定期的に実行するように cron に登録しましょう。

cron については以下にてご説明をしていますので作成方法がわからない方はぜひご参照いただければと思います。

cronを編集する前に、まずはPythonのパスを確認しておきましょう。

which python3

また、auto-stop.py の実行結果を保存しておくディレクトリも作成しておきましょう。logsディレクトリ内に python_logs という名前のディレクトリを作っていますが、そもそも実行結果の保存は不要という方はご対応不要です。

mkdir /home/ec2-user/minecraft/logs/python_logs

上記が完了したら cron の編集をします。

crontab -e

私は anaconda3 という統合開発環境をインストールしているため、Pythonのパスが皆さんとは異なっている可能性がありますのでご注意ください。

# 定期実行の指定 Pythonのパス 実行プログラム 実行結果の出力先 という書き方になっています。
# 以下の意味は「毎時59分にauto-stop.pyを実行し、実行結果は今日の日付の名前を付けたログファイル内に出力する」
59 */1 * * * /home/ec2-user/anaconda3/bin/python3 /home/ec2-user/minecraft/auto-stop.py > /home/ec2-user/minecraft/logs/python_logs/`date +\%Y-\%m-\%d`.log 2>&1

まとめ

これで定期的に auto-stop.py を実行し、誰もサーバーにいなければサーバーソフトを停止のうえでインスタンスを停止させることができますので、従量課金制のAWSを利用している人にとってはインスタンスの停止忘れによる課金を避けられることができます。

AWSを利用していない人でも、システムのシャットダウンに関する行を削除すればマイクラサーバーの停止だけが出来ますので、村人がゾンビに襲われてしまうといった事態を避けることも可能です。

これでマイクラサーバーの運用がさらに効率化できますので、皆さんもぜひ試してみてください。

それではまた。

code, coding, computer

この記事が気に入ったら
フォローしてね!

コメント

コメントする

目次