在Discord上创建了一个Minecraft服务器的故事

首先

你好。我是一名宅男大学生。
作为一名宅男大学生,我只有在线上的朋友。因此,我经常玩在线游戏。今天我要讲述的就是这个故事。

由于作为大学生我住在合作社公寓,所以无法设置服务器并解除端口限制以进行游戏。因此,平时我会在AWS的EC2上搭建服务器。

このサーバーをボイスチャットツールのDiscordから起動及び停止できるようにすれば大変便利です。

请原谅前言绵长,请随意。

EC2的准备工作

简介

image.png

    discord-bot EC2 t2.microインスタンス
    game-server EC2 t2.largeインスタンス

システムの概略はこのような感じです。ここでのポイントは

    discordのレスポンス用とサーバー用に2つのインスタンスを用意
    それぞれのインスタンスはアカウント内セキュリティグループで管理

准备两个实例的原因

因为没有钱。要运行Minecraft服务器,至少需要t2.large服务器(内存8GB)。然而,Discord机器人需要保持活跃状态,但无法一直运行昂贵的t2.large服务器。

实例的设置

EC2のインスタンスの起動方法は多くの方が説明してくださっているので割愛します。

请在中文中感到自在地重述以下内容,只需提供一种选项:

Discord机器人

インスタンスタイプ:t2.micro
インバウンドルール:無編集でOK(SSHの22ポートのみ)
コンソール:AWSコマンドが使えること

discord的机器人使用discord.py。
为什么选择Python呢?因为我喜欢它。

游戏服务器

实例类型:t2.large
入站规则:添加TCP25565端口(用于Minecraft)

实施

创建discord的机器人账号

请参考这个并创建。
请记下访问令牌。

创建一个Discord机器人

我会在 Discord bot 实例中进行操作。
在 SSH 连接的终端中执行以下命令。

python3 -m pip install -U discord.py

我們將編寫主要的程式碼。在這個例子中,當輸入「$start minecraft」時,會啟動伺服器;而當輸入「$stop minecraft」時,會停止伺服器。



import discord
import subprocess
import paramiko
import time

# 自分のBotのアクセストークンに置き換えてください
TOKEN = 'your access token'
# game-serverのインスタンスidを指定してください
INSTANCEID = 'your instance id'

# 接続に必要なオブジェクトを生成
client = discord.Client()

# ***************************
# ***    処理関数
# ***************************
class DiscordBOT:
    def __init__(self, client):
        self.SSHClient = None

    async def main(self, discord_event):
        get_text = discord_event.content
        send_text = ""

        if "$start minecraft" in get_text:
            # インスタンスの起動
            subprocess.call("aws ec2 start-instances --instance-ids {}".format(INSTANCEID), shell=True)
            time.sleep(3)

            # インスタンスが起動するまで待機
            subprocess.call("aws ec2 wait instance-running --instance-ids {}".format(INSTANCEID), shell=True)
            time.sleep(3)

            # インスタンスのIPアドレスを取得
            proc = subprocess.run(["aws ec2 describe-instances --instance-ids {} --query 'Reservations[*].Instances[*].PublicIpAddress' --output text".format(INSTANCEID)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            ip_add = proc.stdout.decode("utf-8")
            ip_add = ip_add.replace(".", "-").replace("\n", "")
            self.server_ip = ip_add
            time.sleep(3)

            # SSH接続クライアント作成
            self.SSHClient = paramiko.SSHClient()
            self.SSHClient.set_missing_host_key_policy(paramiko.WarningPolicy())
            self.SSHClient.connect('ec2-{}.compute-1.amazonaws.com'.format(ip_add), username='root', password='')
            time.sleep(2)

            # SSHでminecraftサーバー起動
            stdin, stdout, stderr = self.SSHClient.exec_command("java -Xmx4096M -Xms4096M -jar server.jar nogui")
            for x in stdout:
                print(x)
            for x in stderr:
                print(x)
            time.sleep(2)

            # 接続用のIPアドレスをdiscordに送信
            send_text = "インスタンスの起動とminecraftサーバーへの接続に成功しました。\n サーバー起動後は {} で接続できます".format(ip_add.replace("-", "."))

        elif "$stop minecraft" in get_text:
            # サーバーの停止
            self.SSHClient.connect('ec2-{}.compute-1.amazonaws.com'.format(ip_add), username='root', password='')
            time.sleep(2)
            stdin, stdout, stderr = self.SSHClient.exec_command("stop")
            self.SSHClient.close()

            # インスタンスの停止
            subprocess.call("aws ec2 stop-instances --instance-ids {}".format(INSTANCEID), shell=True)
            send_text = "サーバーの停止が完了しました。"

        if send_text:
            await discord_event.channel.send(send_text)


discordbot = DiscordBOT(client)

@client.event
async def on_ready():
    print('ログインしました')

# on get message
@client.event
async def on_message(message):
    if message.author.bot:
        return

    await discordbot.main(message)

# Botの起動とDiscordサーバーへの接続
client.run(TOKEN)

これをEC2上で実行すれば完成です。

nohup python3 main.py &

game-serverの設定

javaをインストールする必要があります。
こちらを参考にしてください。

さらにはrootユーザーのホームディレクトリにminecraftのサーバースクリプト(server.jar)を保存しておきます。

また、SSH接続を公開鍵認証を用いて行いますのでそちらの設定を行います。
こちらもすでに記事がありますので紹介させていただきます。

在EC2实例之间无需密码登录的方法

设置安全组

いまのままでは、awsコマンドによっての遠隔起動ができません。そのためそれを許可するためにそれぞれを同じセキュリティグループに入れてやる必要があります。

image.png

选择分配/替换此IAM角色

image.png

创建新的 IAM 角色后,只需将每个实例添加到相同的 IAM 角色即可完成准备工作。

結果

daw.png

image.png

平安无事地进行了移动。太令人高兴了。

bannerAds