[PYTHON] The story of launching a Minecraft server from Discord

Introduction

Hello. I'm a Yin-Yang college student. As a college student, my friends are only online. Therefore, I often play online games. This time is the story.

As a college student, I live in a co-op condominium, so even if I set up a server, I can't open the port and can't play. Therefore, I usually set up a server on AWS EC2.

It would be very convenient to be able to start and stop this server from the voice chat tool Discord.

Then the introduction has become longer, but please.

EC2 preparation

Overview

image.png

--__discord-bot EC2 t2.micro instance __ --__game-server EC2 t2.large instance __

The outline of the system looks like this. The point here is

--Two instances are prepared, one for discord response and one for server --Each instance is managed by an in-account security group

Reasons to have two instances

Because I don't have money. At least t2.large performance (8GB of memory) is required to run the minecraft server. But the Discord bot needs to be active all the time, and you can't always launch the more expensive t2.large.

Instance settings

Many people have explained how to start an instance of EC2, so I will omit it.

discord-bot Instance type: t2.micro Inbound rule: No editing OK (SSH 22 port only) Console: AWS commands can be used

The discord BOT uses discord.py. The reason for Python is that I like it. ..

game-server Instance type: t2.large Inbound rule: Added TCP25565 port (for Minecraft)

Implementation

Creating a discord bot account

Please refer to here to create it. Make a note of the access token.

Creating a discord-bot

Work with __discord-bot instance __. Execute the following in the terminal connected by SSH.

python3 -m pip install -U discord.py

Write the main source code. This time, start the server when you type $ start minecraft, and stop the server when you type $ stop minecraft.



import discord
import subprocess
import paramiko
import time

#Replace with your bot's access token
TOKEN = 'your access token'
# game-Please specify the instance id of server
INSTANCEID = 'your instance id'

#Generate the objects needed for the connection
client = discord.Client()

# ***************************
# ***Processing function
# ***************************
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:
            #Launch an instance
            subprocess.call("aws ec2 start-instances --instance-ids {}".format(INSTANCEID), shell=True)
            time.sleep(3)

            #Wait for the instance to start
            subprocess.call("aws ec2 wait instance-running --instance-ids {}".format(INSTANCEID), shell=True)
            time.sleep(3)

            #Get the IP address of the instance
            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)

            #Create SSH connection client
            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)
            
            #Start minecraft server with SSH
            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)

            #Send the IP address for connection to discord
            send_text = "You have successfully launched an instance and connected to a minecraft server.\n After starting the server{}You can connect with".format(ip_add.replace("-", "."))

        elif "$stop minecraft" in get_text:
            #Server outage
            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()

            #Stop instance
            subprocess.call("aws ec2 stop-instances --instance-ids {}".format(INSTANCEID), shell=True)
            send_text = "The server stop is complete."

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


discordbot = DiscordBOT(client)

@client.event
async def on_ready():
    print('You are now logged')

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

    await discordbot.main(message)

#Launching a bot and connecting to a Discord server
client.run(TOKEN)

Run this on EC2 and you're done.

nohup python3 main.py &

game-server settings

You need to install java. Please refer to here.

In addition, save the minecraft server script (server.jar) in the root user's home directory.

Also, since the SSH connection is made using public key authentication, make the settings there. There is already an article here, so I will introduce it.

How to log in between EC2 instances without an SSH password

Security group settings

As it is, remote startup by the aws command is not possible. So you need to put each in the same security group to allow it.

image.png

Select Assign / Replace __ for this __IAM Role

image.png

After creating a new IAM role, add each instance to the same IAM role and you're ready to go.

result

daw.png

image.png

It worked safely. I'm happy.

Recommended Posts

The story of launching a Minecraft server from Discord
The story of remounting the application server
The story of writing a program
The story of a Django model field disappearing from a class
The story of blackjack A processing (python)
A story about operating a GCP instance from Discord
The story of making a lie news generator
A story of creating 16 * 16 dots from a Digimon photo
The story of making a mel icon generator
The story of moving from Pipenv to Poetry
The story of sys.path.append ()
SSH login to the target server from Windows with a click of a shortcut
A story that reduces the effort of operation / maintenance
Calculate volume from the two-dimensional structure of a compound
Make a BOT that shortens the URL of Discord
Python points from the perspective of a C programmer
The story of making a music generation neural network
A story about changing the master name of BlueZ
Zip 4 Gbyte problem is a story of the past
A story that analyzed the delivery of Nico Nama.
Plug commands into Minecraft server from Discord text chat
The story of switching from WoSign to Let's Encrypt for a free SSL certificate
The story of building Zabbix 4.4
[Apache] The story of prefork
The story of creating a VIP channel for in-house chatwork
Different from the import type of python. from A import B meaning
I found the cause of mysterious communication of Minecraft server (Spigot)
The story of copying data from S3 to Google's TeamDrive
Create a correlation diagram from the conversation history of twitter
After all, the story of returning from Linux to Windows
The story of creating a database using the Google Analytics API
The story of making a question box bot with discord.py
A story about a GCP beginner building a Minecraft server on GCE
A Python script that allows you to check the status of the server from your browser
A story stuck with the installation of the machine learning library JAX
The story of Python and the story of NaN
A story about predicting prefectures from the names of cities, wards, towns and villages with Jubatus
The story of participating in AtCoder
A formula that simply calculates the age from the date of birth
A story that struggled to handle the Python package of PocketSphinx
Existence from the viewpoint of Python
The story of making a standard driver for db with python.
[Python] Get the update date of a news article from HTML
The story of creating a site that lists the release dates of books
The story of the "hole" in the file
The story of making a module that skips mail with python
Best 3 from the impressions of reading a new shell programming textbook
Set up a dummy SMTP server in Python and check the operation of sending from Action Mailer
A story about creating a program that will increase the number of Instagram followers from 0 to 700 in a week
A story that visualizes the present of Qiita with Qiita API + Elasticsearch + Kibana
The story of a Parking Sensor in 10 minutes with GrovePi + Starter Kit
The story of making a university 100 yen breakfast LINE bot with Python
The story of having a hard time introducing OpenCV with M1 MAC
The story of developing a web application that automatically generates catchphrases [MeCab]
A story of a person who started aiming for data scientist from a beginner
The story of making a sound camera with Touch Designer and ReSpeaker
The story of the escape probability of a random walk on an integer grid
The story of making a package that speeds up the operation of Juman (Juman ++) & KNP
Get the average salary of a job with specified conditions from indeed.com
From a book that makes the programmer's way of thinking interesting (Python)
The story of trying to reconnect the client