2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

マイクラ鯖をDiscordから起動する

Last updated at Posted at 2025-01-13

目的

Discordボットを使ってMinecraftサーバを操作できるようにする

準備

以下の導入が済んでいることを前提として話を進めていきます。

  • Discordボット
  • Minecraftサーバ
  • tmux
  • Java
  • Python3
    ※この記事では上記すべてのやり方を解説しません。

実行環境

OS

Ubuntu Server 24.04.1 LTS

Minecraftサーバ

CurseForge for Minecraft 1.16.5 - 36.2.34

Java

OpenJDK 11.0.25

(2025/01/13 時点)

結論

以下のコードを実行することで操作ができます。

discordbot.py
# This example requires the 'message_content' intent.

import discord
import subprocess

intents = discord.Intents.default()
intents.message_content = True

client = discord.Client(intents=intents)
command = []
def execute(shell_script):
    subprocess.run(shell_script, shell=True)

@client.event
async def on_ready():
    print(f'We have logged in as {client.user}')

@client.event
async def on_message(message):  # メッセージへの対応
    if message.author.bot:  # 送信者がBOTのとき
        return
    elif message.content.strip():  # メッセージが空白でないとき
        try:
            await message.channel.send('wait...')
            command = message.content.split()
            match command[0]:
                case 'open':    # 先頭がopenのとき
                    await message.channel.send('now '+command[0]+'ing...')
                    execute('tmux new -s '+command[1]+' -d')
                    execute('tmux send-keys -t '+command[1]+' "cd server/'+command[1]+'"'+' ENTER')
                    execute('tmux send-keys -t '+command[1]+' "java -Xms2G -Xmx12G -jar forge-1.16.5-36.2.34.jar" ENTER')
                case 'close':   # 先頭closeのとき
                    execute('tmux send-keys -t '+command[1]+' "stop" ENTER')
                    execute('tmux send-keys -t '+command[1]+' "exit" ENTER')
        except Exception as e:  # エラーが発生したとき
            await message.channel.send(f'error: {e}')
    else:
        return

with open('token.txt', encoding='utf-8') as f:
    client.run(f.read())   # Discordにログイン

使い方

1. ディレクトリ構成をそろえる

上記のdiscordbot.pyと同じディレクトリに token.txtserver ディレクトリを作成する。

ディレクトリ構成
┝ discordbot.py
┝ token.txt
└ server

2. Minecraftサーバを準備する

server ディレクトリから1段階深いディレクトリにサーバのjarファイルがくるようにする。

ディレクトリ構成(一部省略)
┝ discordbot.py
┝ token.txt
└ server
    └ 250113_test
        ┝ config
        ┝ eula.txt
        ┝ forge-1.16.5-36.2.34.jar
        ├ minecraft_server.1.16.5.jar

3. token.txtにDiscordボットのトークンをペーストする

token.txt
s3dfD3ydf...

※余計なことは書かない!

3. 実行するときのコマンドを書き換える

discordbot.py(前後省略)
@client.event
async def on_message(message):  # メッセージへの対応
    if message.author.bot:  # 送信者がBOTのとき
        return
    elif message.content.strip():  # メッセージが空白でないとき
        try:
            await message.channel.send('wait...')
            command = message.content.split()
            match command[0]:
                case 'open':    # 先頭がopenのとき
                    await message.channel.send('now '+command[0]+'ing...')
                    execute('tmux new -s '+command[1]+' -d')
                    execute('tmux send-keys -t '+command[1]+' "cd server/'+command[1]+'"'+' ENTER')
                    execute('tmux send-keys -t '+command[1]+' "java -Xms2G -Xmx12G -jar forge-1.16.5-36.2.34.jar" ENTER')

上記のうち一番下の "java -Xms2G -Xmx12G -jar forge-1.16.5-36.2.34.jar" 部分を書き換える。

①サーバファイル

forge-1.16.5-36.2.34.jar をサーバファイル名(拡張子含む)に書き換え

②最小メモリ容量

-Xms2G を割り当てる最小のメモリ容量に書き換え
例)-Xms1G -Xms4G

③最大メモリ容量

②最小メモリ容量と同様、-Xmx12G を割り当てる最大のメモリ容量に書き換え

3. discordbot.pyを実行

シェルから以下のコマンドを実行する。

python3 discordbot.py

解説

import discord

ディスコードボットを動かすために必要なモジュール

import subprocess

Pythonからシェルコマンドを実行するために必要

intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)

ディスコードボットの設定

command = []

送られたメッセージリスト型にする先をつくる

def execute(shell_script):
    subprocess.run(shell_script, shell=True

シェルでのコマンドを使いやすくする

@client.event
async def on_ready():
    print(f'We have logged in as {client.user}')

適切にディスコードへとログインできたかの確認

@client.event
async def on_message(message):  # メッセージへの対応
    if message.author.bot:  # 送信者がBOTのとき
        return

ボット同士で会話しないようにする

elif message.content.strip():  # メッセージが空白でないとき
    try:
        await message.channel.send('wait...')
    except Exception as e:  # エラーが発生したとき
        await message.channel.send(f'error: {e}')
else:
    return

何かしらの読み取れるメッセージが送られたとき、wait... と返信する

command = message.content.split()

メッセージを区切ってリスト型に変換

match command[0]:
    case 'open':    # 先頭がopenのとき
    case 'close':   # 先頭closeのとき

メッセージの先頭がopen のときとclose のときの分岐

await message.channel.send('now '+command[0]+'ing...')

ディスコードにnow opening...now closeing... と送信
closeingのスペルがおかしいのは無視

execute('tmux new -s '+command[1]+' -d')

tmuxで新しいセッションを作る
(subprocessをそのまま使うと鯖にstopコマンドが使えなくなってしまうため)

execute('tmux send-keys -t '+command[1]+' "cd server/'+command[1]+'"'+' ENTER')

サーバーディレクトリに移動

execute('tmux send-keys -t '+command[1]+' "java -Xms2G -Xmx12G -jar forge-1.16.5-36.2.34.jar" ENTER')

マイクラサーバーを起動

execute('tmux send-keys -t '+command[1]+' "stop" ENTER')

マイクラサーバーを停止

execute('tmux send-keys -t '+command[1]+' "exit" ENTER')

tmuxのセッションを停止

with open('token.txt', encoding='utf-8') as f:
    client.run(f.read())   # Discordにログイン

おわりに

最後まで読んでいただき、ありがとうございます。
何か不具合や要望がありましたら、気軽に連絡してください。

参考記事

プログラミング初心者のためのQiita記事投稿テンプレート

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?