Check out the project on notabug

The end goal

I usually start all of my projects with a clear vision of what that project should accomplish. It is almost time for the second semester to start and I have not gotten my fix of accomplishment for the week. I have a problem but it’s a good problem that is more of a nice side of me. But anyways. So what is the end goal? I want to have a discord bot that people are able to send messages to to be able to turn on and off a Minecraft server when we want to play. This way, I do not have to SSH into the server potentially doing something wrong. I don’t do anything wrong but I figured for anyone who might want to start the server. My friends for example. They are not very experienced with Linux and servers and all that stuff. So this may be a good and simple method of starting and stopping a Minecraft server.

Why?

Can’t you just leave it running?

When you are the last one leaving the house, do you leave your lights on and the water running? EXACTLY no one in their right mind would do such a thing. Running a Minecraft server required the events in the Minecraft world to be computed which has a significant CPU and RAM consumption to put it bluntly. Therefore it is nice that I am able to start the Minecraft server through discord.

How does it work?

Discord has this thing called an Application Programming Interface API for short. This allows us to import a library(chunk of code modules that will allow us to talk to the discord gods) and use it in our code mumbo jumbo to get stuff done. So I use a Linux shell command to start the server and some programming languages allow you to import a library to execute a shell command. That is the OS library. Discord allows us to create bots which look like regular users that have a little bot sign after their names of course. You would not want to get confused between a real person and a computer on the internet since those things are becoming smarter that us nowadays. Then basically, i write some code like:

if you type .server_start in the discord message box, 
    Start the server if it's not already running or
		tell them that it's already running.
		
if you type .server_stop in the discord message box, 
    Stop the server if it's not already stopped or
		tell them that it's already stopped.
		
if you type .server_status in the discord message box, 
    Show the number of players and the latency.

And that’s pretty much all you have to know if you are not interested in seeing the actual code but if you do… Read on…

The code. spOokyyyyy…

The language that is used to write this bot is python. Here is the script.

#!/usr/bin/python
import time
import discord
import os

from mcstatus import MinecraftServer

from discord.ext import commands

server = MinecraftServer.lookup("YOURSERVER.COM")
try:
    status = server.status()
    print("The server has {0} players and replied in {1} ms".format(status.players.online, status.latency))
except:
    print("Server offline")

client = commands.Bot(command_prefix = ".")

@client.event
async def on_ready():
    print("Ready")
    
@client.command()
async def server_start(ctx):
    print("Starting server")
    try:
        status = server.status()
        print("```css\nThe server is already running")
        await ctx.send("```css\nThe server is already running\n```")
    except:
        await ctx.send('Starting minecraft server. Please wait a few seconds...')
        os.system("cd /home/$USER/ && nohup java -Xmx1024M -Xms1024M -jar server.jar nogui &")
        time.sleep(7)
        await ctx.send("```css\nServer started\n```")

@client.command()
async def server_status(ctx):
    print("Server status requested.")
    try:
        status = server.status()
        print("The server has {0} players and replied in {1} ms".format(status.players.online, status.latency))
        await ctx.send("**Server status**\n```diff\n+ Players: {0} \n+ Latency: {1} ms```".format(status.players.online, status.latency))
    except:
        await ctx.send("**Server status**\n```diff\n- Server is offline\n```")
    
@client.command()
async def server_stop(ctx):
    print("Server shutdown requested.")
    try:
        status = server.status()
        if status.players.online !=0:
            await ctx.send("**Server shutdown requested:**\n```diff\n- Sorry. server can only be shutdown if no one is playing.\nPlayers: {0}```".format(status.players.online))
        else:
            await ctx.send("**Server shutdown requested:**\n```diff\n+ Server sucessfully shut down.```")
            os.system("killall java")
    except:
        await ctx.send('```diff\n- Server is not running\n```')
    
    status = server.status()
    
@client.command()
async def server_help(ctx):
    print("Server shutdown requested.")
    await ctx.send("```css\nMinecraft server controller\nMade By Az\nWritten in python\n```\n```arm\nCOMMAND : WHAT HAPPENS\n```\n```arm\n.server_help : Show this message.\n\n.server_start : Starts the minecraft server, playable after 5 to 10 seconds.\n\n.server_status : Shows player numbers & latency or whether the server is offline.\n\n.server_stop : Stops the server only when no one is playing.\n```")
		
client.run('Discord-api-key-here...')

If your heart has stopped beating, I can understand. You either have no idea what this means or you are cringing since I could have done things way better. But you know what? It meets my end goal. And that’s all that counts. I am aware that there may be better already made things that already do this kind of job, but thinking that would be missing the point. I wanted to do this project for it’s learning experience.

How long did it take

Half a day really. I started at 2 in the afternoon cause I woke up late. I worked on it for most of the time. Taking pauses to eat and go relieve myself from time to time. but I eventually got it done. I followed some tutorials, copied and pasted some code from the internet, scrapped what did not work, had to scrap some ideas and workaround some things but eventually pulled through.

What’s next

Well you see, people still have to turn off the server through the program after playing otherwise, it will stay on and consume resources. So the next thing to add to it is a way to automatically shut doen the server after sometime if it sees that no one is online.


UPDATE

I wrote all the above quite a while ago. Now all needed features are implemented. Check the notabug project. If you read through all of it, Thank you so very much