⛏️

Mod 無し Minecraft で動く Chat Bot + α

2020/09/28に公開

これはなに?

以下が出来る Minecraft Bot を実装しました。

  • 複数チャットツール (LINE/Slack/Discord) で動く Bot
  • Minecraft Server の Whitelist 操作
  • Minecraft Server へのログイン/ログアウトを各種チャットツールに通知
  • Minecraft のゲーム情報のメトリクスを Prometheus フォーマットで吐く

ソースコードは以下になります。

モチベーション

Minecraft Server を運用していますが、以下の悩みがありました。

  • 知らない人に荒らされたくないから Whitelist でメンバー管理をしたい
  • でも管理者である自分が居ない間も Whitelist の操作が出来るようにしたい
  • けど安易に管理者 (Minecraft 内で管理用のコマンドを実行できる) 権限を与えたくない

このような Minecraft を操作する Chat Bot は既にいくつかありましたがそのどれもが Bot から Minecraft Server の World データなどが保存されたファイルを直接読みに行くようなもので、 RCON による操作のみで完結するような Bot が存在しなかったため自分で実装しました。

インストール

Bot が利用できるようになるまで設定していきます。

動作確認環境は以下です。(Releaseしたバイナリはクロスコンパイル済みですが以下の環境以外での動作は未確認です)

  • MacOS Mojave 10.14.6

  • Docker Container (alpine:3.8)

    • on CentOS Linux release 7.7.1908 (3.10.0-1062.18.1.el7.x86_64)

ダウンロード

以下の方法があります。

  • バイナリをダウンロードする

  • go get コマンドを利用してインストールする

    • 以下のコマンドを実行することで $GOPATH/bin 以下にバイナリが落とされます。

go get -u github.com/ShotaKitazawa/minecraft-bot/cmd/minecraft-bot
  • Docker Image を利用する
    • kanatakita/minecraft-bot を利用できます。
docker pull kanatakita/minecraft-bot

起動方法

以下を前提にして、起動方法の一例を紹介します。(各パラメータについて詳しくは GitHub の README をご覧ください)

  • ダウンロード方法は、「バイナリをダウンロードする」
  • LINE, Slack, Discord に一つずつ Bot を用意
  • Minecraft Server と同ホストにて Bot を起動

Minecraft Server のセットアップ

Minecraft Server の server.properties 設定ファイルを以下のように編集し、RCON を有効化します。

server.properties
enable-rcon=true
rcon.password=(適当なパスワード)
rcon.port=25575

LINE Bot セットアップ

以下の URL より LINE Bot のセットアップをし、 チャネルシークレットチャネルアクセストークン(ロングターム) を取得します。また Webhook設定 より Webhook URL を設定します。

LINE Bot の設定方法については他にわかり易い記事がたくさんあるため当記事では省略します。

Slack Bot セットアップ

以下の URL より Slack Bot のセットアップをし、 Bot User OAuth Access Token を取得します。

Slack Bot の設定方法についても同様に省略します。

Discord Bot セットアップ

以下の URL より Discord Bot のセットアップをし、TOKEN を取得します。

Discord Bot の設定方法についても同様に省略します。

設定ファイルの作成

  • config.toml という名前で以下の内容のファイルを作成します。
config.toml
minecraft-hostname = "(自分の Minecraft Server のドメイン名)"

[[bot.line]]
endpoint = "/linebot"  #  「LINE Bot セットアップ」 手順で設定した Webhook URL の path
channel-secret = "XXX" #  「LINE Bot セットアップ」 手順で取得した Channel Secret
channel-token = "XXX"  #  「LINE Bot セットアップ」 手順で取得した Channel Token

[[bot.slack]]
token = "XXX"          #  「Slack Bot セットアップ」 手順で取得した Token

[[bot.discord]]
token = "XXX"          #  「Discord Bot セットアップ」 手順で取得した Token

[rcon]
host = "127.0.0.1"
port = 25575
password = "XXX"       #  「Minecraft Server のセットアップ」 手順で設定した RCON パスワード

[sharedmem]
mode = "local"

起動

上で作成した設定ファイルを用いて Bot を起動します。

$ minecraft-bot -f config.toml
WARN[0000] "bot.line[].group-ids" is empty, push notification is disabled.
WARN[0000] "bot.slack[].channel-ids" is empty, push notification is disabled.
WARN[0000] "bot.discord[].channel-ids" is empty, push notification is disabled.

Warning メッセージが出ますが無視してください。 (Minecraft へログイン/ログアウトの通知を各種チャットに送信する 手順を実施すると当警告は出なくなります)

使い方

Bot を起動したら各種チャットにてコマンドの実行が可能です。チャットに !help と打ち込むと実行可能なコマンド一覧が表示されます。

デモ

Qiita だとサイズ制限で動作しなかったので GitHub の README をご覧ください。

Appendix

Minecraft へログイン/ログアウトの通知を各種チャットに送信する

ログイン/ログアウト通知を各種チャットに送るには、送信したい グループ (LINE) / チャンネル (Slack, Discord) の ID を知り、それを Bot のパラメータに与えて実行する必要があります。以下の手順でグループ ID を取得することが出来ます。

  1. パラメータを与えないで Bot を実行
  2. 各種チャットにて !id と発言し、グループIDを取得する
  3. 取得したグループIDをパラメータに与えてBotを再実行

ログイン/ログアウト通知を含むデモも GitHub の README をご覧ください。

Prometheus で Minecraft のユーザ情報のメトリクス取得

Bot の /metrics に対して GET すると Prometheus フォーマットでメトリクスを吐いてくれます。

$ curl -s localhost:8080/metrics
...
# HELP minecraft_health_gauge Minecraft User's Health
# TYPE minecraft_health_gauge gauge
minecraft_health_gauge{username="kanatakita_com"} 12.546666145324707
# HELP minecraft_pos_x_gauge Minecraft User's Position of X axis
# TYPE minecraft_pos_x_gauge gauge
minecraft_pos_x_gauge{username="kanatakita_com"} 496.1026611328125
# HELP minecraft_pos_y_gauge Minecraft User's Position of Y axis
# TYPE minecraft_pos_y_gauge gauge
minecraft_pos_y_gauge{username="kanatakita_com"} 29
# HELP minecraft_pos_z_gauge Minecraft User's Position of Z axis
# TYPE minecraft_pos_z_gauge gauge
minecraft_pos_z_gauge{username="kanatakita_com"} 181.3526611328125
# HELP minecraft_user_info Minecraft Login Users
# TYPE minecraft_user_info gauge
minecraft_user_info{username="kanatakita_com"} 1
# HELP minecraft_xp_level_gauge Minecraft User's Xp Level
# TYPE minecraft_xp_level_gauge gauge
minecraft_xp_level_gauge{username="kanatakita_com"} 48

GitHub リポジトリ/dashboard 以下にあるファイルを Grafana に食わせると、以上のメトリクスを利用したグラフも表示できます。

minecraft_users.png

ステート管理に Redis を利用

設定ファイルに以下のように追記すると、Bot のステート管理にインメモリではなく Redis を利用することが出来ます。

config.toml
[sharedmem]
mode = "redis"

[sharedmem.redis]
host = "127.0.0.1"
port = 6379

この Redis を RDB (Redis DataBase) や AOF (Append Only File) を用いて永続化設定することで、Bot のプロセスが再起動した際も以下のステートを永続化することが出来ます。

  • Prometheus のメトリクスとして、過去にログインしたことのあるユーザを保存しておく

まとめ

Mod 無しの Minecraft で動作する Chat Bot を実装しました。

抽象化や並行処理などを用いて実装したため、その辺りの勉強にもなりたのしかったです。

GitHubで編集を提案

Discussion