Skip to content

Commit

Permalink
Merge branch 'mysql' into Python
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaSlui authored Feb 25, 2023
2 parents c946c28 + 6291af6 commit 727336c
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 35 deletions.
16 changes: 11 additions & 5 deletions cogs/checkip.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
from discord import Embed
from mcstatus import JavaServer
from utils import Utils


class CheckIP(commands.Cog):
def __init__(self, bot):
self.bot = bot

@bridge.bridge_command(aliases=["checkserverip", "check"], description="Checks if an Aternos-IP is free to use.")
async def checkip(self, ctx, address = None):
async def checkip(self, ctx, address=None):
if address is None:
return await ctx.respond("Please provide a Aternos server ip!\nExample: example.aternos.me")
if not address.endswith(".aternos.me"):
Expand All @@ -16,18 +18,22 @@ async def checkip(self, ctx, address = None):
return await ctx.respond("Please provide a valid Aternos server ip!\nExample: example.aternos.me")
nip = address.split(".")[0]
if len(nip) > 20:
return await ctx.respond("Aternos IPs can only be 20 characters long, please try a shorter one. Yours is " + str(len(nip)) + " characters long.")
return await ctx.respond(
"Aternos IPs can only be 20 characters long, please try a shorter one. Yours is " + str(
len(nip)) + " characters long.")
if len(nip) < 4:
return await ctx.respond("Aternos IPs must be at least 4 characters long, please try a longer one. Yours is " + str(len(nip)) + " characters long.")
return await ctx.respond(
"Aternos IPs must be at least 4 characters long, please try a longer one. Yours is " + str(
len(nip)) + " characters long.")
await ctx.defer()
embed = Embed()
server = await JavaServer.async_lookup(address)
stat = await server.async_status()
if stat.version.name == "⚠ Error":
embed.description=f"**{address}** is free to use!\nTo use it as your server address, head to **[the options of your server](https://aternos.org/options)**"
embed.description = f"**{address}** is free to use!\nTo use it as your server address, head to **[the options of your server](https://aternos.org/options)**"
embed.colour = Utils.Colors.green
else:
embed.description=f"**{address}** is already taken!"
embed.description = f"**{address}** is already taken!"
embed.colour = Utils.Colors.red
await ctx.respond(embed=embed)

Expand Down
8 changes: 6 additions & 2 deletions cogs/cogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from discord.ext.commands import slash_command
from discord.ext import commands
from discord import Option
#from discord.errors import ExtensionAlreadyLoaded
# from discord.errors import ExtensionAlreadyLoaded
from utils import Utils


class Cogs(commands.Cog):
def __init__(self, bot):
self.bot = bot
Expand All @@ -18,7 +20,8 @@ def getcogs(self, ctx):
cogs.append(file[:-3])
return cogs

@slash_command(description='Only the owners of the bot can run this command', guild_ids=Utils.get_data()['FeatureGuilds'])
@slash_command(description='Only the owners of the bot can run this command',
guild_ids=Utils.get_data()['FeatureGuilds'])
async def cogs(self, ctx, action: Option(choices=["Load", "Unload", "Reload"]), cog: Option(autocomplete=getcogs)):
if ctx.author.id not in self.info['Owners']:
return
Expand Down Expand Up @@ -46,5 +49,6 @@ async def cogs(self, ctx, action: Option(choices=["Load", "Unload", "Reload"]),
raise error
await ctx.respond(f"{action}ed {cog} and reloaded all commands!")


def setup(bot):
bot.add_cog(Cogs(bot))
7 changes: 5 additions & 2 deletions cogs/error.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from discord.ext import commands


class Error(commands.Cog):
def __init__(self, bot):
self.bot = bot
Expand All @@ -7,13 +9,14 @@ def __init__(self, bot):
async def on_command_error(self, ctx, error):
if isinstance(error, commands.CommandNotFound):
return await ctx.respond("That command doesn't exist!")
await ctx.respond ("An unknown error has occured!\nThis has been logged")
await ctx.respond("An unknown error has occured!\nThis has been logged")
raise error

@commands.Cog.listener()
async def on_application_command_error(self, ctx, error):
await ctx.respond ("An unknown error has occured!\nThis has been logged")
await ctx.respond("An unknown error has occured!\nThis has been logged")
raise error


def setup(bot):
bot.add_cog(Error(bot))
4 changes: 3 additions & 1 deletion cogs/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from discord import Embed
from utils import Utils


class Info(commands.Cog):
def __init__(self, bot):
self.bot = bot
Expand All @@ -21,13 +22,14 @@ async def info(self, ctx):
**Guilds:** {len(self.bot.guilds)}
**Users:** {sum(x.member_count for x in self.bot.guilds)}
**API Latency:** {round(self.bot.latency*1000)}ms
**API Latency:** {round(self.bot.latency * 1000)}ms
**Protocol Latency:** {latency}ms
[[Invite]](https://discord.com/api/oauth2/authorize?client_id=889197952994791434&permissions=274878286912&scope=bot%20applications.commands) [[Support]](https://discord.gg/Ukr89GrMBk) [[Github]](https://github.com/BlackFurORG/pingernos) [[Privacy Policy]](https://gist.github.com/MiataBoy/20fda9024f277ea5eb2421adbebc2f23) [[Terms of Service]](https://gist.github.com/MiataBoy/81e96023a2aa055a038edab02e7e7792)
"""
embed.colour = Utils.Colors.blue
await ctx.respond(embed=embed)


def setup(bot):
bot.add_cog(Info(bot))
5 changes: 4 additions & 1 deletion cogs/privacy.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
from discord.ext import commands, bridge
from discord import Embed
from utils import Utils


class Privacy(commands.Cog):
def __init__(self, bot):
self.bot = bot

@bridge.bridge_command(description = "Shows the privacy policy of the bot.")
@bridge.bridge_command(description="Shows the privacy policy of the bot.")
async def privacy(self, ctx):
embed = Embed()
embed.description = f"{self.bot.user.name} saves a minimal amount of data to allow for its functionality. As we work on regaining full functionality, we do not currently collect anything On our database storage, we currently only have server IPs and guild IDs stored. For any concerns, Mail to [email protected] or join https://discord.gg/Ukr89GrMBk"
embed.colour = Utils.Colors.blue
await ctx.respond(embed=embed)


def setup(bot):
bot.add_cog(Privacy(bot))
31 changes: 24 additions & 7 deletions cogs/setserver.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
from discord.ext import commands#, bridge
from discord.ext import commands, bridge
from utils import Utils


class SetServer(commands.Cog):
def __init__(self, bot):
self.bot = bot

#@bridge.bridge_command(aliases=["set"], description="Set the default server to use if no argument is provided in the status command.")
#async def setserver(self, ctx, server = None):
# if server is None:
# return await ctx.respond("Please provide a server IP.")
# await ctx.defer()
#This is up to Miataboy to implement
@bridge.bridge_command(aliases=["set"],
description="Set the default server to use if no argument is provided in the status command.")
async def setserver(self, ctx, server=None):
if server is None:
return await ctx.respond(
"Please provide a server IP to register to this guild. If an IP is already registered, it'll be overwritten")
if not server.endswith(".aternos.me"):
server += ".aternos.me"
if server.count(".") > 2:
return await ctx.respond("Please provide a valid Aternos server ip!\nExample: example.aternos.me")
cursor = await Utils.mysql_login()
database = cursor.cursor()
database.execute(
"INSERT INTO server (guild_id, server_ip) VALUES (%s, %s) ON DUPLICATE KEY UPDATE server_ip = %s",
(ctx.guild_id, server, server))
cursor.commit()
database.close()
cursor.close()
return await ctx.respond(f'The IP has been set to {server}. Use `status` without an argument to view it.')


def setup(bot):
bot.add_cog(SetServer(bot))
29 changes: 23 additions & 6 deletions cogs/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,27 @@
from discord.ext import commands, bridge
from discord import Embed, utils as dutils
from utils import Utils


class Status(commands.Cog):
def __init__(self, bot):
self.bot = bot

@bridge.bridge_command(aliases=["s"], description="Get the server status")
async def status(self, ctx, serverip = None):
async def status(self, ctx, serverip=None):
if serverip is None:
#Until Miataboy implements the default server, this will appear
return await ctx.respond("Please provide a valid Aternos server ip!\nExample: example.aternos.me")
cursor = await Utils.mysql_login()
database = cursor.cursor()
database.execute("SELECT server_ip FROM server WHERE guild_id = %s", [ctx.guild.id])
try:
result = database.fetchone()[0]
except TypeError:
database.close()
cursor.close()
return await ctx.respond("Sorry, but this server does not have an IP registered. Please use `setserver` for that.")
serverip = result
database.close()
cursor.close()
if not serverip.endswith(".aternos.me"):
serverip += ".aternos.me"
if serverip.count(".") > 2:
Expand All @@ -22,24 +34,29 @@ async def status(self, ctx, serverip = None):
return await ctx.respond("Uh oh! The protocol took too long to respond! This will likely fix itself.")
embed = Embed(title=serverip)
if stat.version.name == "§4● Offline":
embed.description = "We are not able to gather info from offline servers, sorry!\nProtocol Latency: " + str(round(stat.latency)) + "ms\n\nIf you believe this is wrong, please [join our discord server](https://discord.gg/G2AaJbvdHT)."
embed.description = "We are not able to gather info from offline servers, sorry!\nProtocol Latency: " + str(
round(
stat.latency)) + "ms\n\nIf you believe this is wrong, please [join our discord server](https://discord.gg/G2AaJbvdHT)."
embed.colour = Utils.Colors.red
embed.timestamp = dutils.utcnow()
embed.set_footer(text="Command executed by " + ctx.author.name + "#" + ctx.author.discriminator)
elif stat.version.name == "⚠ Error":
embed.description = "Server does not exist\nProtocol Latency: " + str(round(stat.latency)) + "ms\n\nIf you believe this is wrong, please [join our discord server](https://discord.gg/G2AaJbvdHT)."
embed.description = "Server does not exist\nProtocol Latency: " + str(round(
stat.latency)) + "ms\n\nIf you believe this is wrong, please [join our discord server](https://discord.gg/G2AaJbvdHT)."
embed.colour = Utils.Colors.red
embed.timestamp = dutils.utcnow()
embed.set_footer(text="Command executed by " + ctx.author.name + "#" + ctx.author.discriminator)
else:
embed.add_field(name="**__Status__**", value="Online", inline=True)
embed.add_field(name="**__Players__**", value=str(stat.players.online) + "/" + str(stat.players.max), inline=True)
embed.add_field(name="**__Players__**", value=str(stat.players.online) + "/" + str(stat.players.max),
inline=True)
embed.add_field(name="**__Software__**", value=stat.version.name, inline=True)
embed.add_field(name="**__MOTD__**", value=Utils.remove_colors_from_string(stat.description), inline=False)
embed.colour = Utils.Colors.green
embed.timestamp = dutils.utcnow()
embed.set_footer(text="Command executed by " + ctx.author.name + "#" + ctx.author.discriminator)
await ctx.respond(embed=embed)


def setup(bot):
bot.add_cog(Status(bot))
22 changes: 16 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
from discord import Intents, Status, Activity, ActivityType
from discord.ext.bridge import Bot
from utils import Utils

data = Utils.get_data()
intents = Intents(guilds=True, guild_messages=True)
#intents.message_content = True #Uncomment this if you use prefixed command that are not mentions
bot = Bot(intents=intents, command_prefix=data['Prefix'], status=Status.dnd, activity=Activity(type=ActivityType.watching, name="you (prefix: @mention)"))
bot.load_extensions("cogs") #Loads all cogs in the cogs folder
bot.help_command = Utils.HelpCmd() #Disables the default help command
# intents.message_content = True #Uncomment this if you use prefixed command that are not mentions
bot = Bot(intents=intents, command_prefix=data['Prefix'], status=Status.dnd,
activity=Activity(type=ActivityType.watching, name="you (prefix: @mention)"))
bot.load_extensions("cogs") # Loads all cogs in the cogs folder
bot.help_command = Utils.HelpCmd() # Disables the default help command
BOOTED = False


@bot.listen()
async def on_connect():
print('Connected to Discord!')
cursor = await Utils.mysql_login()
database = cursor.cursor()
database.execute("CREATE TABLE IF NOT EXISTS server (guild_id VARCHAR(255) PRIMARY KEY, server_ip TEXT NOT NULL)")
database.close()


@bot.listen()
async def on_ready():
global BOOTED
if BOOTED:
print ("Reconnect(?)")
print("Reconnect(?)")
if not BOOTED:
#await bot.sync_commands() #You might need to uncomment this if the slash commands aren't appearing
# await bot.sync_commands() #You might need to uncomment this if the slash commands aren't appearing
print(f'Logged in as {bot.user}')
print('------')
BOOTED = True


bot.run(data['Token'])
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
py-cord==2.4.0
python-dotenv==0.21.0
mcstatus==10.0.1
asyncmy==0.2.5
asyncmy==0.2.5
mysql-connector-python==8.0.32
28 changes: 24 additions & 4 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,37 @@
from os import getenv
from sys import exit as sysexit
from discord.ext.commands import HelpCommand
import mysql.connector as mysql

try:
from dotenv import load_dotenv

load_dotenv()
except ModuleNotFoundError:
print('You did not install the dotenv module! You will not be able to use a .env file.')
try:
from mcstatus import JavaServer
from mcstatus.pinger import PingResponse
except ModuleNotFoundError:
print('You did not install the mcstatus module! Exiting now...')
sysexit()


class Utils:
@staticmethod #This is a static method, you can call it without creating an instance of the class, but does not have access to the class or its attributes (self)
@staticmethod # This is a static method, you can call it without creating an instance of the class, but does not have access to the class or its attributes (self)
def remove_colors_from_string(text) -> str:
text = sub(r"§[0-9a-r]", "", text)
return text

class Colors:
blue = 0xadd8e6
red = 0xf04747
green = 0x90ee90
orange = 0xfaa61a

@staticmethod
def get_data() -> dict:
usejson = False #Set to True to a config.json
usejson = False # Set to True to a config.json
if usejson:
try:
with open('config.json', 'r', encoding="UTF-8") as file:
Expand Down Expand Up @@ -58,13 +66,25 @@ def get_data() -> dict:
print('You did not fill out the environment variables! Exiting now...')
sysexit()
return data

@staticmethod
async def get_server_status(serverip: str) -> dict:
async def get_server_status(serverip: str) -> PingResponse:
server = await JavaServer.async_lookup(serverip)
stat = await server.async_status()
return stat

@staticmethod
async def mysql_login():
data = Utils.get_data()

return mysql.connect(
host=data['Database']['Host'],
user=data['Database']['User'],
password=data['Database']['Password'],
database=data['Database']['Database'])

class HelpCmd(HelpCommand):
async def send_bot_help(self, mapping):
channel = self.get_destination()
await channel.send("Type in `/` to see the commands!", reference=self.context.message, mention_author=False, delete_after=15)
await channel.send("Type in `/` to see the commands!", reference=self.context.message, mention_author=False,
delete_after=15)

0 comments on commit 727336c

Please sign in to comment.