diff --git a/bot.py b/bot.py index 4d9d40a..9914f2c 100755 --- a/bot.py +++ b/bot.py @@ -8,8 +8,11 @@ prefixes = ["/"] client = commands.Bot(command_prefix=prefixes, case_insensitive=True) client.prefixes = prefixes +# Load this cog first so the other cogs can use properties initialized here +client.load_extension("cogs.events") + for file in os.listdir("./cogs"): - if file.endswith(".py"): + if file.endswith(".py") and not (file.startswith(("events",))): client.load_extension(f"cogs.{file[:-3]}") client.run("NzYwNTI5NDY2MDI3MDE2MjUy.X3NYQg.Nz3bwxgltlayMStfT7F-OCbx9pE") diff --git a/cogs/events.py b/cogs/events.py new file mode 100644 index 0000000..48413a0 --- /dev/null +++ b/cogs/events.py @@ -0,0 +1,59 @@ +import discord +from discord.ext import commands + +from data import constants +from functions import checks, bannedWords + + +class Events(commands.Cog): + def __init__(self, client): + self.client = client + + @commands.Cog.listener() + async def on_connect(self): + print("Connected") + + @commands.Cog.listener() + async def on_ready(self): + print("Ready") + self.client.banned_words = bannedWords.load() + + @commands.Cog.listener() + async def on_message(self, message): + if message.guild is None: + return + + # The bot sends a confirmation message after banning a word, + # allow the bot to send this message. + # This also makes it possible for the bot to send an embed + # with that message in #ModLogs. + # + # Allow mods to use these words as well to whitelist them. + if message.author.id == constants.wcbID or checks.isModPlus(message): + return + + # Check for banned words + for word in self.client.banned_words: + if word in message.content.lower(): + await message.delete() + return await self.bannedWordEmbed(message, word) + + async def bannedWordEmbed(self, message, word): + modLogs = message.guild.get_channel(constants.ModLogs) + + embed = discord.Embed(colour=discord.Colour.red()) + + iconFile = discord.File("files/images/server_icon.png", "icon.png") + embed.set_author(name="Bad Word Usage", icon_url="attachment://icon.png") + + embed.add_field(name="Author", value="{} #{}".format(message.author.display_name, message.author.discriminator)) + embed.add_field(name="Channel", value=message.channel.mention) + embed.add_field(name="Word", value=word) + embed.add_field(name="Zin", value=message.content, inline=False) + embed.set_footer(text=embed.timestamp) + + await modLogs.send(embed=embed, file=iconFile) + + +def setup(client): + client.add_cog(Events(client)) diff --git a/cogs/modcommands.py b/cogs/modcommands.py index f28fee0..60710f7 100755 --- a/cogs/modcommands.py +++ b/cogs/modcommands.py @@ -1,6 +1,6 @@ import discord from discord.ext import commands -from functions import checks +from functions import checks, bannedWords, embeds class ModCommands(commands.Cog): @@ -15,15 +15,51 @@ class ModCommands(commands.Cog): # Delete the original message await ctx.message.delete() - # Attach the server icon as a file - file = discord.File("files/images/server_icon.png", filename="icon.png") - - # Set up the embed - embed = discord.Embed(colour=discord.Colour.orange()) - embed.set_author(name=ctx.author.display_name, icon_url="attachment://icon.png") + embed, file = embeds.modEmbed(ctx.author.display_name) embed.description = arg await ctx.send(embed=embed, file=file) + @commands.command(name="Blacklist", aliases=["Bl"]) + @commands.check(checks.isModPlus) + async def blacklist(self, ctx, word=None): + if word is None: + return await ctx.send("You did not provide a word to blacklist.") + + if not bannedWords.ban_word(word): + await ctx.message.add_reaction("❌") + return await ctx.send("This word has already been blacklisted.") + + await ctx.message.add_reaction("✅") + self.client.banned_words.append(word.lower()) + return await ctx.send("Blacklisted **{}**.".format(word)) + + @commands.command(name="Whitelist", aliases=["Wl"]) + async def whitelist(self, ctx, word=None): + if word is None: + return await ctx.send("You did not provide a word to whitelist.") + + if not bannedWords.remove_word(word): + await ctx.message.add_reaction("❌") + return await ctx.send("This word has not been blacklisted.") + + await ctx.message.add_reaction("✅") + self.client.banned_words.remove(word.lower()) + return await ctx.send("Whitelisted **{}**.".format(word)) + + @commands.command(name="Blacklisted", aliases=["Words"]) + async def bannedwords(self, ctx): + embed, file = embeds.modEmbed("Blacklisted Words") + + banned = sorted(self.client.banned_words) + + # Can't send empty embed + if not banned: + embed.description = "No words have been blacklisted yet." + else: + embed.description = " - ".join(banned) + + return await ctx.send(embed=embed, file=file) + def setup(client): - client.add_cog(ModCommands(client)) \ No newline at end of file + client.add_cog(ModCommands(client)) diff --git a/cogs/serverstatus.py b/cogs/serverstatus.py new file mode 100644 index 0000000..f7fd2cc --- /dev/null +++ b/cogs/serverstatus.py @@ -0,0 +1,73 @@ +import discord +from discord.ext import commands +from mcstatus import MinecraftServer + + +class ServerStatus(commands.Cog): + def __init__(self, client): + self.client = client + + @commands.group(name="Ping", aliases=["Status"], case_insensitive=True, invoke_without_command=True) + async def ping(self, ctx): + servers = {"Earth": "25568", "Moon": "25567"} + + # List of colours for the amount of servers that are online + upColours = [discord.Colour.red(), discord.Colour.orange(), discord.Colour.green()] + + embed = discord.Embed() + embed.set_author(name="Status") + + # Amount of servers that are online + upCounter = 0 + + # Add field for all the servers (for-loop so nothing has to be changed for future servers) + for server in servers: + latency, up = self.getLatency(servers[server]) + upCounter += up + embed.add_field(name=server, value=latency, inline=False) + + # Set the embed colour + embed.colour = upColours[upCounter] + + # Bot's latency + embed.add_field(name="WorldCraft Bot", value=f":green_circle: {round(self.client.latency * 1000)}ms") + + await ctx.send(embed=embed) + + @ping.command(name="Earth", aliases=["E", "S1", "Server1"]) + async def earth(self, ctx): + latencyEmbed = self.serverLatencyEmbed("Earth", "25568") + await ctx.send(embed=latencyEmbed) + + @ping.command(name="Moon", aliases=["M", "S2", "Server2"]) + async def moon(self, ctx): + latencyEmbed = self.serverLatencyEmbed("Moon", "25567") + await ctx.send(embed=latencyEmbed) + + # Latency for only 1 server, avoid code duplication + def serverLatencyEmbed(self, server, ip): + embed = discord.Embed() + embed.set_author(name="{} Status".format(server)) + latency, up = self.getLatency(ip) + embed.description = latency + embed.colour = discord.Colour.green() if up == 1 else discord.Colour.red() + return embed + + def getLatency(self, server): + ip = "81.82.224.207:" + up = 1 + + minecraftServer = MinecraftServer.lookup(ip + server) + + try: + # Online + latency = f":green_circle: Server replied in {minecraftServer.ping()}ms." + except: + # Offline + up = -1 + latency = ":red_circle: Server is offline." + return latency, up + + +def setup(client): + client.add_cog(ServerStatus(client)) \ No newline at end of file diff --git a/credentials.json b/credentials.json new file mode 100644 index 0000000..282ffda --- /dev/null +++ b/credentials.json @@ -0,0 +1,12 @@ +{ + "worldcraft_discord": { + "ip": "192.168.1.251", + "username": "worldcraft_discord", + "password": "aquev5vcwhLwTdRt" + }, + "worldcraft": { + "ip": "192.168.1.251", + "username": "worldcraft_discord", + "password": "aquev5vcwhLwTdRt" + } +} diff --git a/data/constants.py b/data/constants.py index b9e55e9..f9a9d52 100755 --- a/data/constants.py +++ b/data/constants.py @@ -17,3 +17,6 @@ WorldCraft = 683422015394545665 adminRoles = [roleAdmin, roleOwner] modPlusRoles = [roleAdmin, roleMod, roleOwner] + +# Channels +ModLogs = 760807882899193867 diff --git a/files/banned_words.json b/files/banned_words.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/files/banned_words.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/functions/bannedWords.py b/functions/bannedWords.py new file mode 100644 index 0000000..8d72cae --- /dev/null +++ b/functions/bannedWords.py @@ -0,0 +1,37 @@ +import json + + +def load(): + with open("files/banned_words.json", "r") as fp: + return json.load(fp) + + +def write(words): + with open("files/banned_words.json", "w") as fp: + json.dump(words, fp) + + +def ban_word(word: str): + words = load() + + # Already been banned + if word.lower() in words: + return False + + # Add to the list of words + words.append(word.lower()) + write(words) + return True + + +def remove_word(word: str): + words = load() + + # Not banned + if word.lower() not in words: + return False + + # Unban word + words.remove(word.lower()) + write(words) + return True diff --git a/functions/embeds.py b/functions/embeds.py new file mode 100644 index 0000000..1e8d206 --- /dev/null +++ b/functions/embeds.py @@ -0,0 +1,12 @@ +import discord + + +def modEmbed(author): + embed = discord.Embed(colour=discord.Colour.orange()) + + # Attach the server icon as a file + file = discord.File("files/images/server_icon.png", filename="icon.png") + + embed.set_author(name=author, icon_url="attachment://icon.png") + + return embed, file