From 255e04a2516b06ef25a22de5c6c727b68f06a543 Mon Sep 17 00:00:00 2001 From: Jumpyvonvagabond <36978560+Jumpyvonvagabond@users.noreply.github.com> Date: Tue, 5 May 2020 11:19:26 -0700 Subject: [PATCH] hotfix for issues introduced in the bug fix i test these updates i swear --- settings.py | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++ utility.py | 211 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 477 insertions(+) create mode 100644 settings.py create mode 100644 utility.py diff --git a/settings.py b/settings.py new file mode 100644 index 0000000..bca6d85 --- /dev/null +++ b/settings.py @@ -0,0 +1,266 @@ +import discord +from discord.ext import commands +from discord.ext.commands import bot, MemberConverter, TextChannelConverter +import json +import cfg +def dump(): + with open('config.json', 'w') as f: + json.dump(cfg.data, f, indent=4) +class Settings(commands.Cog): + def __init__(self, bot): + self.bot = bot + self._last_member = None + @commands.command(aliases=['cfgrld', 'settingsreload']) + async def configreload(self, ctx): + try: + cfg.reload() + except: + embed = cfg.buildembed("Config Reload", "Config could not be reloaded, please redownload the bot data from [here](https://github.com/Jumpyvonvagabond/Setsuna/releases)") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Config Reload", "Successfully reloaded\nIf errors persist, please redownload the bot data from [here](https://github.com/Jumpyvonvagabond/Setsuna/releases)") + await ctx.send(embed=embed) + + @commands.command() + async def prefix(self, ctx, prefix = None): + if prefix != None: + if ctx.message.author.guild_permissions.administrator: + cfg.data['prefix'] = prefix + dump() + embed = cfg.buildembed("Prefix", f"The command prefix has been set to `{prefix}`") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Prefix", "This command requires administrator server permissions") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Prefix", f"The command prefix for this server is `{prefix}`") + await ctx.send(embed=embed) + + @commands.command() + async def botowner(self, ctx, owner = None): + async def listowners(ctx, owner): + embed = discord.Embed(title="List of Owners", description=ctx.guild.name, colour=discord.Colour.blue()) + counter = 0 + while counter < 10: + for owner in cfg.data["ownerid"]: + counter += 1 + try: + member = await MemberConverter().convert(ctx, str(owner)) + except: + embed.add_field(name=f'Owner: {owner}', value='Not a member of this server', inline=False) + else: + embed.add_field(name=f'Owner: {owner}', value=str(member), inline=False) + break + pages = len(cfg.data['ownerid'])//10 + if pages < 1: + pages = 1 + embed.set_footer(text=f'Page 1 of {pages}') + await ctx.send(embed=embed) + if any(identification in str(ctx.message.author.id) for identification in str(cfg.data["ownerid"])): + try: + member = await MemberConverter().convert(ctx, owner) + cfg.data['ownerid'].append(member.id) + dump() + await listowners(ctx, owner) + except: + await listowners(ctx, owner) + else: + listowners(ctx, owner) + + @commands.command() + async def welcome(self, ctx, payload = None, *, message = None): + if ctx.message.author.guild_permissions.manage_channels: + if payload != None: + if payload.lower() == "message": + if message == None: + embed = cfg.buildembed("Welcome", "You didn't enter a welcome message") + await ctx.message.send("You forgot to input a new welcome message!") + else: + cfg.data['welcome']['message'] = message + dump() + embed = cfg.buildembed("Welcome", "You Have Changed the Welcome Message") + embed.add_field(name="It is Now", value=message) + await ctx.send(embed=embed) + elif payload.lower() == "channel": + try: + message = await TextChannelConverter().convert(ctx, (message[1])) + except: + embed = cfg.buildembed("Welcome", "Invalid channel input") + await ctx.send(embed=embed) + else: + cfg.data['welcome']['channel'] = message.id + dump() + embed = cfg.buildembed("Welcome", f"Channel has been changed to{message.mention}") + await ctx.send(embed=embed) + elif payload.lower() == "toggle": + if cfg.data['welcome']['enabled'] == False: + cfg.data['welcome']['enabled'] = True + dump() + self.bot.reload_extension('cogs.utility') + embed = cfg.buildembed("Welcome", "Welcome messages have been set to True") + await ctx.send(embed=embed) + else: + cfg.data['welcome']['enabled'] = False + dump() + cog = self.bot.get_cog('Utility') + self.bot.remove_listener(cog.on_member_join) + embed = cfg.buildembed("Welcome", "Welcome messages have been set to False") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Welcome Info", f"Here is a list of options, and their current values for {ctx.guild.name}") + embed.add_field(name="Welcome message", value=f"To make a custom welcome message, use '{ctx.prefix}welcome message [message]'\nTo ping the user who joined, say {{MENTION}} where you want them to be pinged\nTo say the name of the server, use {{SERVER}}", inline=False) + embed.add_field(name="Channel", value=f"To change the welcome channel, use '{ctx.prefix}welcome channel [channel]'", inline=False) + embed.add_field(name="Toggle", value=f"To toggle the welcome message on and off, use '{ctx.prefix}welcome toggle'\n", inline=False) + await ctx.channel.send(embed=embed) + else: + embed = cfg.buildembed("Welcome", "This command requires the manage channels permission") + await ctx.send(embed=embed) + + @commands.command(aliases=['wf']) + async def wordfilter(self, ctx, payload = None, *, word = None): + if ctx.message.author.guild_permissions.manage_channels: + if payload != None: + if payload.lower() == 'toggle': + cog = self.bot.get_cog('Administration') + if cfg.data['wordfilter'] == False: + cfg.data['wordfilter'] = True + self.bot.reload_extension('cogs.administration') + dump() + embed = cfg.buildembed("Word Filter", "Word Filter has been set to True") + await ctx.send(embed=embed) + else: + cfg.data['wordfilter'] = False + self.bot.remove_listener(cog.on_message) + dump() + embed = cfg.buildembed("Word Filter", "Word Filter has been set to False") + await ctx.send(embed=embed) + elif payload.lower() == 'remove': + try: + cfg.data['slurs'].remove(word.lower()) + dump() + except: + embed = cfg.buildembed("Word Filter", f"{word} could not be found in the words list") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Word Filter", f"{word} has been successfully removed") + await ctx.send(embed=embed) + elif payload.lower() == 'list': + embed = cfg.buildembed("Word Filter", cfg.data['slurs']) + await ctx.send(embed=embed) + elif payload.lower() == 'add': + if len(cfg.data['slurs']) < 10: + if len(word) < 100: + cfg.data['slurs'].append(word.lower()) + dump() + embed = cfg.buildembed("Word Filter", f"{word} added successfully") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Word Filter", f"invalid argument. For a list of arguments, use\n `{ctx.prefix}wordfilter`") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Word Filter", "Info") + embed.add_field(name="Toggle", value=f"To toggle the word filter on and off, use `{ctx.prefix}wordfilter toggle`", inline=False) + embed.add_field(name="Add", value=f"To add a word to the filter, use `{ctx.prefix}wordfilter add [word]`\nYou can use a phrase or a word\nWords/phrases must be under 100 characters", inline=False) + embed.add_field(name="Remove", value=f"To remove a word from the filter, use `{ctx.prefix}wordfilter remove [word]`", inline=False) + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Word Filter", "This command requires the manage channels permission") + await ctx.send(embed=embed) + + @commands.command(aliases=['pb']) + async def pineappleboard(self, ctx, payload = None, setting= None): + if ctx.message.author.guild_permissions.manage_channels: + if payload.lower() == 'toggle': + if cfg.data['pineappleboard']['enabled'] == False: + cfg.data['pineappleboard']['enabled'] = True + self.bot.reload_extension('cogs.utility') + embed = cfg.buildembed("Pineappleboard", "Pineappleboard has been enabled") + await ctx.send(embed=embed) + else: + cfg.data['pineappleboard']['enabled'] = False + cog = self.bot.get_cog('Utility') + self.bot.remove_listener(cog.on_raw_reaction_add) + embed = cfg.buildembed("Pineappleboard", "Pineappleboard has been disabled") + await ctx.send(embed=embed) + dump() + + elif payload.lower() == 'count': + try: + int(setting) + except: + embed = cfg.buildembed("Pineappleboard", "the command requires a number as the input") + await ctx.send(embed=embed) + else: + cfg.data['pineappleboard']['count'] = int(setting) + dump() + embed = cfg.buildembed("Pineappleboard", f"Pineapple threshold changed to {setting}") + await ctx.send(embed=embed) + elif payload.lower() == 'channel': + try: + payload = await TextChannelConverter().convert(ctx, str(setting)) + except: + embed = cfg.buildembed("Pineappleboard", "Invalid text channel input") + await ctx.send(embed=embed) + else: + cfg.data['pineappleboard']['channel'] = setting.id + dump() + embed = cfg.buildembed("Pineappleboard", f"Pineappleboard channel changed to {setting.mention}") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Pineappleboard Settings", "Here's a list of settings") + embed.add_field(name="Count", value=f"To change the number of pineapples required to get a message added to the board, use {ctx.prefix}pineappleboard count [number]", inline=False) + embed.add_field(name="Channel", value=f"To change the channel that messages added to the board are sent to, use {ctx.prefix}pineappleboard channel [channel]", inline=False) + embed.add_field(name="Toggle", value=f"To toggle the pineappleboard on and off, use {ctx.prefix}pineappleboard toggle", inline=False) + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Pineappleboard", "This command requires the manage channels permission") + await ctx.send(embed=embed) + + @commands.command() + async def log(self, ctx, payload = None, setting = None, delmessagechan = None): + if ctx.message.author.guild_permissions.manage_channels: + if payload.lower() == 'channel': + try: + payload = await TextChannelConverter().convert(ctx, str(setting)) + except: + embed = cfg.buildembed("Log", "Invalid text channel input") + await ctx.send(embed=embed) + else: + cfg.data['logchannel'] = payload.id + dump() + elif payload.lower() == 'toggle': + if cfg.data['log'] == False: + cfg.data['log'] = True + self.bot.reload_extension('cogs.utility') + dump() + embed = cfg.buildembed("Log", "Logging has been changed to True") + await ctx.send(embed=embed) + else: + cfg.data['log'] = False + cog = self.bot.get_cog('Utility') + self.bot.remove_listener(cog.on_raw_message_delete) + self.bot.remove_listener(cog.on_member_ban) + dump() + embed = cfg.buildembed("Log", "Logging has been changed to False") + await ctx.send(embed=embed) + elif payload.lower() == 'deletedmessages': + try: + delmessagechan = await TextChannelConverter().convert(ctx, str(delmessagechan)) + except: + embed = cfg.buildembed("Log", "Invalid text channel input") + await ctx.send(embed=embed) + else: + cfg.data['deletedmessageschannel'] = delmessagechan.id + dump() + else: + embed = cfg.buildembed("Log Settings", "Here's a list of log settings") + embed.add_field(name="Channel", value=f"To change the channel used for logging, use {ctx.prefix}log channel [channel]") + embed.add_field(name="Toggle", value=f"To toggle logging on and off, use {ctx.prefix}log toggle") + embed.add_field(name="Deleted Messages", value=f"To change the deleted messages channel, use {ctx.prefix}log deletedmessages [channel]") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed("Log", "This command requires the manage channels permission") + await ctx.send(embed=embed) + +def setup(bot): + bot.add_cog(Settings(bot)) \ No newline at end of file diff --git a/utility.py b/utility.py new file mode 100644 index 0000000..f6e94af --- /dev/null +++ b/utility.py @@ -0,0 +1,211 @@ +import discord +from discord.ext import commands +from discord.ext.commands import bot, MemberConverter, TextChannelConverter, EmojiConverter, PartialEmojiConverter, RoleConverter +import json +import asyncio +import cfg +class Utility(commands.Cog): + def __init__(self, bot): + self.bot = bot + self._last_member = None + + @commands.command() + async def invite(self, ctx): + if 'VANITY_URL' in ctx.guild.features: + await ctx.send(ctx.guild.vanity_invite()) + else: + invites = await ctx.guild.invites() + await ctx.send(invites[0]) + + @commands.command() + async def actionlist(self, ctx, event, member = None): + if ctx.message.author.guild_permissions.manage_messages == False: + await ctx.channel.send("You don't have permission to use this command)") + else: + if member == None: + try: + member = await MemberConverter().convert(ctx, event) + except: + try: + embed = cfg.buildembed(f'List of {event.title()}s', None) + action = getattr(discord.AuditLogAction,event) + async for entry in ctx.guild.audit_logs(limit = 15, action=action): + embed.add_field(name = '{0.user}'.format(entry), value = f'{event.title()}'+' to {0.target} Entry ID: {0.id}'.format(entry), inline = True) + await ctx.channel.send(embed=embed) + except: + await ctx.channel.send("You either didn't specify an action, or you didn't specify a user. For a list of actions, use .help actionlist") + else: + try: + embed = cfg.buildembed(f'List of actions by {event.title()}', None) + async for entry in ctx.guild.audit_logs(limit = 15, user=member): + embed.add_field(name = '{0.user}'.format(entry), value = '{0.action} to {0.target} Entry ID: {0.id}'.format(entry), inline = True) + await ctx.channel.send(embed=embed) + except: + await ctx.channel.send("No user was found by that name") + else: + try: + member = await MemberConverter().convert(ctx, member) + except: + await ctx.channel.send("I couldn't find the user you were looking for") + else: + embed = cfg.buildembed(f'Action list for {member}', None) + action = getattr(discord.AuditLogAction,event) + async for entry in ctx.guild.audit_logs(limit = 15, action=action, user=member): + embed.add_field(name = '{0.user}'.format(entry), value = f'{event.title()}'+' to {0.target} Entry ID: {0.id}'.format(entry), inline = True) + await ctx.channel.send(embed=embed) + + @commands.command(aliases=['banlog']) + async def banlist(self, ctx, page = None): + embed = cfg.buildembed('List of Banned Users', None) + try: + page = abs(int(page)) + floor = (page*10) - 10 + except: + page = 1 + floor = 0 + if floor < 0: + floor = 0 + bans = await ctx.guild.bans() + counter = 0 + while counter < 10: + embed.add_field(name=bans[floor].user, value=bans[floor].reason, inline=False) + counter += 1 + floor += 1 + embed.set_footer(text=f'Page {page} of {len(bans)//10}') + await ctx.send(embed=embed) + + @commands.command(aliases=['se', 'showemoji', 'stealemoji', 'stealemote', 'viewemote', 'viewemoji']) + async def showemote(self, ctx, emote = None): + if emote == None: + await ctx.send("You didn't specify an emote to show") + try: + emote = await EmojiConverter().convert(ctx, emote) + except: + try: + await PartialEmojiConverter().convert(ctx, emote) + except: + cfg.buildembed('Show Emote', "I couldn't find the emote you were looking for") + else: + emote = emote.replace('<', '') + emote = emote.replace('>', '') + emote = emote.rsplit(':', 2) + embed = cfg.buildembed(emote[1], f"ID: {emote[2]}") + embed.set_image(url=f"https://cdn.discordapp.com/emojis/{emote[2]}.png") + await ctx.send(embed=embed) + else: + embed = cfg.buildembed(emote.name, f"ID: {emote.id}") + embed.set_image(url=emote.url) + await ctx.send(embed=embed) + + @commands.command(aliases=['ui', 'userinformation', 'whois']) + async def userinfo(self, ctx, member = None): + try: + member = await MemberConverter().convert(ctx, member) + except: + member = ctx.message.author + if member.status == discord.Status.online: + colour = discord.Colour.green() + elif member.status == discord.Status.offline: + colour = discord.Colour.light_grey() + elif member.status == discord.Status.idle: + colour = discord.Colour.gold() + elif member.status == discord.Status.dnd: + colour = discord.Colour.red() + embed = cfg.buildembed(str(member), 'Information', colour) + embed.add_field(name='Nickname', value=member.display_name, inline=False) + embed.add_field(name="Highest Role", value=member.top_role, inline=False) + embed.add_field(name="Joined", value=member.joined_at, inline=False) + if member.premium_since != None: + embed.add_field(name="Boosted On", value=member.premium_since, inline=False) + else: + embed.add_field(name="Boost Status", value="Not boosting") + embed.set_thumbnail(url=member.avatar_url) + await ctx.send(embed=embed) + + @commands.command() + async def membercount(self, ctx, role = None): + try: + role = await RoleConverter().convert(ctx, role) + except: + embed = cfg.buildembed('Member Count', f'There are {len(ctx.guild.members)} in this server') + await ctx.send(embed=embed) + else: + role = len(role.members) + if role == 1: + embed = cfg.buildembed('Member Count', f'There is 1 member with the {role.name} role in {ctx.guild.name}') + await ctx.send(embed=embed) + else: + embed = cfg.buildembed('Member Count', f'There are {role} members with the {role.name} role in {ctx.guild.name}') + await ctx.send(embed=embed) + + @commands.Cog.listener() + async def on_raw_message_delete(self, deleted_message): + if deleted_message.cached_message == None: + log = self.bot.get_channel(cfg.data['deletedmessageschannel']) + channel = self.bot.get_channel(deleted_message.channel_id) + embed = cfg.buildembed('Message Deleted', f'in {channel.mention}', discord.Colour.red()) + embed.add_field(name='Message ID', value=deleted_message.message_id) + embed.add_field(name='Message Content Unavailable', value="The message wasn't cached in time for it to be logged, sorry") + await log.send(embed=embed) + else: + if not deleted_message.cached_message.author.bot: + log = self.bot.get_channel(cfg.data['deletedmessageschannel']) + channel = self.bot.get_channel(deleted_message.channel_id) + embed = cfg.buildembed('Message Deleted', f'in {channel.mention}', discord.Colour.red()) + embed.add_field(name='Message ID', value=deleted_message.message_id) + embed.add_field(name='Message Author', value=deleted_message.cached_message.author) + embed.add_field(name='Message Author Nickname', value=deleted_message.cached_message.author.display_name) + embed.add_field(name='Message Author Mention (If Available)', value=deleted_message.cached_message.author.mention) + embed.add_field(name='Messasge Content', value=deleted_message.cached_message.content, inline=False) + await log.send(embed=embed) + + @commands.Cog.listener() + async def on_member_ban(self, guild, user): + ban = await guild.fetch_ban(user) + embed = cfg.buildembed("Member banned", f"{str(user)} was banned from {guild}", discord.Colour.red()) + embed.add_field(name="Reason", value=ban.reason) + channel = self.bot.get_channel(cfg.data["logchannel"]) + await channel.send(embed=embed) + + @commands.Cog.listener() + async def on_member_join(self, member): + channel = self.bot.get_channel(cfg.data["welcomechannel"]) + key = {'MENTION': member.mention, 'SERVER': member.guild.name} + await channel.send(cfg.data["welcome"]["message"].format(**key)) + + @commands.Cog.listener() + async def on_raw_reaction_add(self, payload): + if payload.emoji.name == '\N{PINEAPPLE}': + channel = self.bot.get_channel(cfg.data["pineappleboard"]["channel"]) + rchannel= self.bot.get_channel(payload.channel_id) + rmessage = await rchannel.fetch_message(payload.message_id) + for reaction in rmessage.reactions: + if reaction.emoji == '\N{PINEAPPLE}': + reaction = reaction + break + if reaction.count > cfg.data['pineappleboard']['count']: + async for m in channel.history(limit=5): + if int(m.embeds[0].fields[0].value[82:].replace(")", "")) == reaction.message.id: + for r in reaction.message.reactions: + if r.emoji == '\N{PINEAPPLE}': + count = r.count + break + embed = m.embeds[0] + embed.set_footer(text=f'Highest {reaction.emoji}: {count}') + await m.edit(embed=embed) + break + elif reaction.count == cfg.data['pineappleboard']['count']: + if reaction.message.channel != channel: + embed = cfg.buildembed(str(reaction.message.author), reaction.message.content, discord.Colour.gold()) + embed.add_field(name="Original Message", value=f"[Jump Link]({reaction.message.jump_url})", inline=False) + embed.set_thumbnail(url=reaction.message.author.avatar_url) + embed.set_footer(text=f'Highest {reaction.emoji}: {reaction.count}') + att = rmessage.attachments[0] + if att.url.lower().endswith(('png', 'jpeg', 'jpg', 'gif', 'webp')): + embed.set_image(url=att.url) + else: + embed.add_field(name='Message Attachment', value=f'[{att.filename}]({att.url})', inline=False) + await channel.send(embed=embed) + +def setup(bot): + bot.add_cog(Utility(bot)) \ No newline at end of file