async def on_command_error(self, ctx, error): if isinstance(error, commands.CommandInvokeError): msg = f'**{self.client.user.display_name}** does not have permission to change your nickname.' await ctx.send(embed=tools.single_embed_neg(msg)) if isinstance(error, commands.MissingRequiredArgument): msg = f'You must declare a new nickname when using this command.' await ctx.send(embed=tools.single_embed_neg(msg))
async def kick(self, ctx, member: discord.Member, *, reason: str = None): if not await self.admin_cog_on(ctx): return msg = f'Are you sure you want to kick {member.display_name}?' if reason is not None: msg += f'\nReason: {reason}' else: msg += 'A reason was not given.' prompt = await ctx.send(embed=tools.single_embed(msg)) answer = await self.yes_no_buttons(prompt, ctx.author) if answer == 'yes': if reason is None: reason = 'A reason was not given.' try: msg = f'You have been kicked from {ctx.guild.name}.\nReason: {reason}' await member.send(embed=tools.single_embed_neg(msg)) except discord.Forbidden: msg = f'{member.display_name} have been kicked from {ctx.guild.name}.\nReason: {reason}' await ctx.send(embed=tools.single_embed_neg(msg)) await member.kick() await ctx.send(embed=tools.single_embed(f'{member.mention}: **See ya, my guy.** :hiking_boot:')) if answer == 'no': await ctx.send(embed=tools.single_embed(f'Kick cancelled.'))
async def sub(self, ctx, method, member: discord.Member, points: int, *, message: str = None): if not await self.rep_cog_on(ctx): return if message is None: message = 'No additional information given.' if not database.in_members_table(ctx.author): database.add_member(ctx.author) bot_spam = database.get_spam(ctx.guild) message = f'**{ctx.author.display_name}** removed {points} {method} point(s) from **{member.display_name}**.\n'\ f'> {message}' if method == 'pos': database.sub_pos(member, points) await bot_spam.send(embed=tools.single_embed(message)) await self.assign_new_role(member) if method == 'neg': database.sub_neg(member, points) await bot_spam.send(embed=tools.single_embed_neg(message)) await ctx.send( embed=tools.single_embed(f'Your changes have been updated.'))
async def net(self, ctx): bells = await self.get_bells(ctx.author) if bells < 10: await ctx.send(embed=tools.single_embed_neg('You do not have enough bells to buy bug bait!')) return await self.modify_bells(ctx.author, -10) await self.add_collection_insects(ctx.author) async with aiohttp.ClientSession() as session: f = await self.fetch(session, will_url + 'insect/available/' + datetime.now().strftime("%B")) data = json.loads(f) insects = [[k['name'], k["critterpediaFilename"], k['spawnRate']] for k in data] title = 'You bought some bug bait for 10 bells!' verify = False while not verify: try: caught = insects[random.randint(0, len(insects))] spawn = caught[2] if '–' in spawn: spawn = spawn.split('–')[1] # 5% chance if int(spawn) <= 5: if random.randint(0, 20) == 0: if await self.check_collection_insects(ctx.author, caught[0]): msg = f':x: You\'ve already caught: **{caught[0]}**! *RARE*' else: await self.update_collection_insects(ctx.author, caught[0]) msg = f'You caught: **{caught[0]}**! *RARE*' thumbnail = f'{image}insects/{caught[1]}.png' embed = discord.Embed(title=title, description=msg, color=discord.Color.purple()) embed.set_image(url=thumbnail) await ctx.send(embed=embed) verify = True # 20% chance elif 5 < int(spawn) <= 25: if random.randint(0, 10) == 0: if await self.check_collection_insects(ctx.author, caught[0]): msg = f':x: You\'ve already caught: **{caught[0]}**! *UNCOMMON*' else: await self.update_collection_insects(ctx.author, caught[0]) msg = f'You caught: **{caught[0]}**! *UNCOMMON*' thumbnail = f'{image}insects/{caught[1]}.png' embed = discord.Embed(title=title, description=msg, color=discord.Color.blue()) embed.set_image(url=thumbnail) await ctx.send(embed=embed) verify = True else: if await self.check_collection_insects(ctx.author, caught[0]): msg = f':x: You\'ve already caught: **{caught[0]}**! *COMMON*' else: msg = f'You caught: **{caught[0]}**! *COMMON*' await self.update_collection_insects(ctx.author, caught[0]) thumbnail = f'{image}insects/{caught[1]}.png' embed = discord.Embed(title=title, description=msg, color=discord.Color.green()) embed.set_image(url=thumbnail) await ctx.send(embed=embed) verify = True except IndexError: pass
async def check_warnings(self, message): def check(react, user): return react.message.id == cache_msg.id and user.permissions_in( admin_channel).kick_members # if member's warnings are 2 or greater, commence a vote to kick warnings, messages = database.get_warnings(message.author) fmt = [ f'{m[4]} - {m[3]} *Issuer: {discord.utils.get(message.author.guild.members, id=m[5]).display_name}' for m in messages ] if warnings >= 2: admin_channel = database.get_administrative(message.guild) msg = f'**{message.author.display_name}** has reached `{warnings}` warnings. Should they be kicked?\n' \ f'__Past Warnings__\n' + '\n'.join(fmt) embed = discord.Embed(color=discord.Color.red(), description=msg) embed.set_thumbnail(url=message.author.avatar_url) msg = await admin_channel.send(embed=embed) await msg.add_reaction('✔') await msg.add_reaction('❌') await asyncio.sleep(1) cache_msg = await admin_channel.fetch_message(msg.id) yes = 0 while yes < 4: reaction, member = await self.client.wait_for('reaction_add', check=check) if reaction.emoji == '✔': yes = reaction.count msg = f'You have been kicked from {message.guild.name}. The last warning was: "{message}"' await message.author.kick(reason=msg) await admin_channel.send(embed=tools.single_embed_neg( f'{message.author.display_name} has been kicked.'))
async def warn(self, ctx, member: discord.Member, *, message: str = None): if not await self.admin_cog_on(ctx): return def check(react, user): return admin_channel == react.message.channel and not user.bot database.add_warning(member, message, ctx.author) warnings, messages = database.get_warnings(member) fmt = [f'{m[4]} - {m[3]} *Issuer: {discord.utils.get(ctx.guild.members, id=m[5]).display_name}' for m in messages] msg = f'You have received a warning from an administrator or mod in {ctx.guild.name}.\n> "{message}"' try: await member.send(embed=tools.single_embed_neg(msg)) except discord.Forbidden: spam = database.get_spam(ctx.guild) await spam.send(embed=f'{member.mention}: {msg}') embed = discord.Embed(color=discord.Color.red(), description=f'{member.mention} has been warned:\n"{message}"') embed.set_thumbnail(url=member.avatar_url) await ctx.send(embed=embed) if warnings >= 2: admin_channel = database.get_administrative(ctx.guild) msg = f'**{member.display_name}** has reached `{warnings}` warnings. Should they be kicked?\n' \ f'__Past Warnings__\n' + '\n'.join(fmt) embed = discord.Embed(color=discord.Color.red(), description=msg) embed.set_thumbnail(url=member.avatar_url) msg = await admin_channel.send(embed=embed) await msg.add_reaction('✔') await msg.add_reaction('❌') yes = 0 no = 0 limit = 4 while True: try: reaction, reactor = await self.client.wait_for('reaction_add', check=check, timeout=28800) if reaction.emoji == '✔': yes = reaction.count if yes >= limit: break if reaction.emoji == '❌': no = reaction.count if no >= limit: break except asyncio.TimeoutError: embed.add_field(name='Timeout', value='The vote has timed out.') await msg.edit(embed=embed) await msg.clear_reactions() return if yes > no: await member.kick(reason=f'You have been kicked from {ctx.guild.name}. The last warning was: "{message}"') embed.add_field(name='Vote completed', value=f'{member.display_name} has been kicked.') await msg.edit(embed=embed) await msg.clear_reactions() if no > yes: embed.add_field(name='Vote completed', value=f'{member.display_name} has been voted to stay.') await msg.edit(embed=embed) await msg.clear_reactions()
async def update_counter(self, ctx): try: member_stats = self.client.get_channel(706099708434841621) members = [m for m in ctx.guild.members if not m.bot] await member_stats.edit(name=f'Members: {len(members)}') await ctx.send(embed=tools.single_embed('Member count updated!')) except Exception as e: print(e) await ctx.send(embed=tools.single_embed_neg( f'An error occurred when updating the member count.\n{e}'))
async def bug(self, ctx, *, message: str): """ Send a bug report :param ctx: :param message: :return: """ msg = f'A bug report was filed by **{ctx.author.display_name}**.\n**Message**: {message}' if len(ctx.message.attachments) > 0: msg += '\n' + ctx.message.attachments[0].url channels = [c for c in ctx.guild.channels if 'bug-reports'] chan = None for c in channels: if 'bug-report' in c.name: chan = c if chan is not None: await chan.send(embed=tools.single_embed_neg(msg, avatar=ctx.author.avatar_url)) else: owner = self.client.get_user(193416878717140992) await owner.send(msg) await ctx.send(embed=tools.single_embed_neg(f'Your report has been sent. Thank you.'))
async def on_message(self, message): if message.author.bot: return for member in message.mentions: if db.is_afk(member): afk, response = db.get_afk(member) msg = f'**{member.display_name}** is **AFK**.\n' \ f'> {response}' try: await message.author.send(embed=tools.single_embed_neg(msg, avatar=member.avatar_url)) except discord.Forbidden: pass
async def fossil_lookup(self, ctx, *, query=None): credit = discord.utils.get(ctx.guild.members, id=272151652344266762) async with aiohttp.ClientSession() as session: url = f'http://157.245.28.81/all/fossils' f, status = await self.fetch(session, url) data = json.loads(f) if query is not None: for k in data: if query.lower() == k['name']: description = f'```\n' \ f'Value: {k["sell"]} bells\n' \ f'Museum Room: {k["museum"]}```' embed = discord.Embed(title=k['name'], description=description, color=discord.Color.green()) embed.set_image( url= f'http://williamspires.co.uk:9876/Furniture/{k["filename"]}.png' ) embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})' ) await ctx.send(embed=embed) return await ctx.send( embed=tools.single_embed_neg(f'Fossil "{query}" not found.')) else: embeds = [] fossil_list = [] title = 'Fossils' count = 1 for fossil in data: if len(fossil_list) == 25: fossil_list = '\n'.join(fossil_list) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name=f'Fossils Part {count}', value=f'```\n{fossil_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})' ) embeds.append(embed) fossil_list = [] count += 1 else: fossil_list.append( f'{fossil["name"]} {"." * (20 - len(fossil["name"]))} {fossil["sell"]} bells' ) paginator = BotEmbedPaginator(ctx, embeds) await paginator.run()
async def blacklist(self, ctx, *blacklist): if not await self.admin_cog_on(ctx): return exists = [] added = [] for b in blacklist: if database.in_check_blacklist(ctx.guild, b): exists.append(b) else: database.add_to_blacklist(ctx.guild, b) added.append(b) if len(added) > 0: await ctx.send(embed=tools.single_embed(f'Item(s) blacklisted: {", ".join(added)}')) if len(exists) > 0: await ctx.send(embed=tools.single_embed_neg(f'{", ".join(exists)} already blacklisted.'))
async def _filter(self, ctx, *words): if not await self.admin_cog_on(ctx): return exists = [] added = [] for b in words: if database.in_check_filter(ctx.guild, b): exists.append(b) else: database.add_to_filter(ctx.guild, b) added.append(b) if len(added) > 0: await ctx.send(embed=tools.single_embed(f'Item(s) filtered: {", ".join(added)}')) if len(exists) > 0: await ctx.send(embed=tools.single_embed_neg(f'{", ".join(exists)} already filtered.'))
async def remove_filter(self, ctx, *item): if not await self.admin_cog_on(ctx): return void = [] deleted = [] for b in item: if database.in_check_filter(ctx.guild, b): database.remove_from_filter(ctx.guild, b) deleted.append(b) else: void.append(b) if len(deleted) > 0: await ctx.send(embed=tools.single_embed(f'Item(s) removed: {", ".join(deleted)}')) if len(void) > 0: await ctx.send(embed=tools.single_embed_neg(f'{", ".join(void)} not found.'))
async def dig(self, ctx): bells = await self.get_bells(ctx.author) if bells < 10: await ctx.send(embed=tools.single_embed_neg('You do not have enough bells to buy the rights to dig here!')) return await self.modify_bells(ctx.author, -10) await self.add_collection_fossils(ctx.author) async with aiohttp.ClientSession() as session: f = await self.fetch(session, will_url + 'all/fossils') data = json.loads(f) fossils = [[k['name'], k['filename']] for k in data] discovered = fossils[random.randint(0, len(fossils))] if await self.check_collection_fossils(ctx.author, discovered[0]): msg = f':x: You\'ve already discovered: **{discovered[0]}**!' else: await self.update_collection_fossils(ctx.author, discovered[0]) msg = f'You discovered: **{discovered[0]}**!' thumbnail = f'{image}Furniture/{discovered[1]}.png' embed = discord.Embed(title='You bought the rights to dig for 10 bells!', description=msg, color=discord.Color.purple()) embed.set_image(url=thumbnail) await ctx.send(embed=embed)
async def neg(self, ctx, member: discord.Member, *, message: str): # take message from user and send to staff support if await self.can_bypass_cooldown(ctx): self.neg.reset_cooldown(ctx) if not await self.rep_cog_on(ctx): return if ctx.author == member: msg = f'You cannot give yourself a review, {ctx.author.display_name}. :pig: *squee!*' await ctx.send(embed=tools.single_embed(msg)) await ctx.message.delete() return # if len(ctx.message.attachments) < 1: # msg = f'Your negative review is incomplete. Please attach a screenshot or picture verifying your claim.' # await ctx.author.send(embed=tools.single_embed(msg)) # await ctx.message.delete() # return if not database.in_members_table(ctx.author): database.add_member(ctx.author) database.add_neg(member) database.add_reviews_given(ctx.author) staff_support_channel = database.get_administrative(ctx.guild) msg = f'**{member.display_name}** gained 1 negative review from '\ f'**{ctx.author.display_name}**.\n\n'\ f'**{ctx.author.display_name}** said:\n "{message}"' embed = discord.Embed(color=discord.Color.red(), description=msg) try: img = ctx.message.attachments[0].url embed.set_image(url=img) except IndexError: pass embed.set_thumbnail(url=member.avatar_url) await staff_support_channel.send(embed=embed) msg = f'Your review has been submitted and forwarded to staff. Thank you.' await ctx.send(embed=tools.single_embed_neg(msg), delete_after=30) await ctx.message.delete()
async def species_lookup(self, ctx, species): credit = discord.utils.get(ctx.guild.members, id=272151652344266762) async with aiohttp.ClientSession() as session: url = f'{will_url}/villager/species/{species.lower()}' f, status = await self.fetch(session, url) villagers = json.loads(f) if len(villagers) < 1: await ctx.send(embed=tools.single_embed_neg( f'Could not find species "{species}."')) return embeds = [] villager_list = [] for villager in villagers: if len(villager_list) == 25: villager_list = '\n'.join(villager_list) embed = discord.Embed(title=f'{species.capitalize()}', color=discord.Color.green()) embed.add_field(name='\u200b', value=f'```\n{villager_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embeds.append(embed) else: villager_list.append( f'{villager["name"]} {"." * (20 - len(villager["name"]))} {villager["personality"]}' ) if len(villager_list) > 0: villager_list = '\n'.join(villager_list) embed = discord.Embed(title=f'{species.capitalize()}', color=discord.Color.green()) embed.add_field(name='\u200b', value=f'```\n{villager_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embeds.append(embed) paginator = BotEmbedPaginator(ctx, embeds) await paginator.run()
async def villager_lookup(self, ctx, villager): async with aiohttp.ClientSession() as session: url = f'{will_url}/villager/{villager.lower().capitalize()}' f, status = await self.fetch(session, url) if status != 200 or len(f) < 1: await ctx.send(embed=tools.single_embed_neg( f'Could not find villager \"{villager}\"!')) return data = json.loads(f) embed = discord.Embed(title=data['name'], color=discord.Color.green()) embed.add_field(name='Species', value=data['species']) embed.add_field(name='Gender', value=data['gender']) embed.add_field(name='Birthday', value=data['birthday']) embed.add_field(name='Personality', value=data['personality']) embed.add_field(name='Phrase', value=f'\"{data["catchphrase"].capitalize()}\"') embed.add_field(name='Hobby', value=data['hobby']) embed.add_field(name='Favorite K.K. Song', value=data['favoriteSong']) embed.set_thumbnail(url=f'{image_url}{data["filename"]}.png') credit = discord.utils.get(ctx.guild.members, id=272151652344266762) embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') await ctx.send(embed=embed)
async def appraise(self, ctx): bells = await self.get_bells(ctx.author) if bells < 10: await ctx.send(embed=tools.single_embed_neg('You do not have enough bells to buy any art!')) return await self.modify_bells(ctx.author, -10) await self.add_collection_art(ctx.author) async with aiohttp.ClientSession() as session: url = 'http://157.245.28.81/artwork/random' f = await self.fetch(session, url) data = json.loads(f) description = f'**Artist**: {data["artist"]}\n' \ f'**Title**: {data["realArtworkTitle"]}' embed = discord.Embed(title=f'You appraised \"{data["name"]}\" for 10 bells', description=description, color=discord.Color.green()) if data['real'] is False: embed.add_field(name='Appraisal', value=':x: Oh no! It was a fake!') else: embed.add_field(name='Appraisal', value=':white_check_mark: Yes! It\'s real!') await self.update_collection_art(ctx.author, data['name']) embed.set_footer(text='You add the artwork to your collection.') url = f'http://williamspires.co.uk:9876/Furniture/{data["filename"]}.png' embed.set_image(url=url) await ctx.send(embed=embed)
async def on_message(self, message): # search messages for discord links if message is None or message.author.bot: return # verify admin cog is on if not database.admin_cog(message.guild): return # check for mention spamming spam_kick = 5 spam_notify = 3 if len(message.mentions) > 0: global mention_counter if message.author.bot or message.author.permissions_in( message.channel).manage_messages: pass elif message.author.id not in mention_counter: mention_counter[message.author.id] = 1 else: admin_channel = database.get_administrative(message.guild) mention_counter[message.author.id] += 1 if mention_counter[message.author.id] >= spam_kick: msg = f'{message.author.mention} has been kicked for spamming mentions.' embed = discord.Embed(description=msg, color=discord.Color.red()) embed.set_author(name=message.author.display_name, icon_url=message.author.avatar_url) await admin_channel.send(embed=embed) await message.author.kick(reason='Spamming mentions') elif mention_counter[message.author.id] == spam_notify: msg = f'Please stop spamming mentions! If you keep doing this you may be auto-kicked.' try: await message.author.send( embed=tools.single_embed_neg(msg)) except discord.Forbidden: await message.channel.send( embed=tools.single_embed_neg( message.author.mention + ' ' + msg)) msg = f'{message.author.mention} has been notified that they are spamming mentions.\n' \ f'[Jump to Message]({message.jump_url})' embed = discord.Embed(description=msg, color=discord.Color.red()) embed.set_author( name= f'{message.author} | {message.author.display_name}', icon_url=message.author.avatar_url) await admin_channel.send(embed=embed) if len(message.attachments) > 0: global attachment_counter if message.author.bot or message.author.permissions_in( message.channel).administrator: pass elif message.author.id not in attachment_counter: attachment_counter[message.author.id] = 1 else: admin_channel = database.get_administrative(message.guild) attachment_counter[message.author.id] += 1 if attachment_counter[message.author.id] >= spam_kick: msg = f'{message.author.mention} has been kicked for spamming attachments.' embed = discord.Embed(description=msg, color=discord.Color.red()) embed.set_author(name=message.author.display_name, icon_url=message.author.avatar_url) await admin_channel.send(embed=embed) await message.author.kick(reason='Spamming attachments') elif attachment_counter[message.author.id] == spam_notify: msg = f'Please stop spamming attachments! If you keep doing this you may be auto-kicked.' try: await message.author.send( embed=tools.single_embed_neg(msg)) except discord.Forbidden: await message.channel.send( embed=tools.single_embed_neg( message.author.mention + ' ' + msg)) msg = f'{message.author.mention} has been notified that they are spamming attachments.\n' \ f'[Jump to Message]({message.jump_url})' embed = discord.Embed(description=msg, color=discord.Color.red()) embed.set_author( name= f'{message.author} | {message.author.display_name}', icon_url=message.author.avatar_url) await admin_channel.send(embed=embed) if await self.profanity_filter(message ) and not message.author.permissions_in( message.channel).manage_messages: staff_support = database.get_administrative(message.guild) description = f'Author: {message.author.mention} \n' \ f'Message: "{message.content}" \n' \ f'[Jump to Message]({message.jump_url})' embed = discord.Embed(title='Slur/Profanity Detected', description=description, color=discord.Color.red()) embed.set_author( name=f'{message.author} | {message.author.display_name}', icon_url=message.author.avatar_url) try: url = message.attachments[0].url embed.set_image(url=url) except IndexError: pass options = ['🚫', '⚠️', '⭕', '❌'] value = '🚫: Kick\n' \ '⚠️: Warn\n' \ '⭕: Ignore\n' \ '❌: Delete' embed.add_field(name='Staff Options', value=value) prompt = await staff_support.send(embed=embed) def check_react(react, actor): return react.message.id == prompt.id and not actor.bot and actor.permissions_in( staff_support).kick_members while True: embed.remove_field(1) for r in options: await prompt.add_reaction(r) reaction, reactor = await self.client.wait_for( 'reaction_add', check=check_react) # kick if reaction.emoji == options[0]: await prompt.clear_reactions() embed.add_field( name='Confirm', value= f'Are you sure you want to **kick** {message.author.display_name}?', inline=False) await prompt.edit(embed=embed) await prompt.add_reaction('✅') await prompt.add_reaction('❌') reaction, reactor = await self.client.wait_for( 'reaction_add', check=check_react) if reaction.emoji == '✅': try: msg = f'You have been kicked by an administrator or mod in {message.guild.name} for the ' \ f'following content\n' \ f'> "{message.content}"' await message.author.send( embed=tools.single_embed_neg(msg)) except discord.Forbidden: pass # remove confirmation dialogue embed.remove_field(1) embed.remove_field(0) msg = f'{message.author.mention} has been kicked by **{reactor.display_name}**' embed.add_field(name='Action', value=msg, inline=False) await prompt.edit(embed=embed) await prompt.clear_reactions() await message.delete() await message.author.kick( reason='inappropriate or obscene language') break elif reaction.emoji == '❌': await prompt.clear_reactions() # warn elif reaction.emoji == options[1]: embed.remove_field(1) await prompt.clear_reactions() embed.add_field( name='Confirm', value= f'Are you sure you want to **warn** {message.author.mention}?', inline=False) await prompt.edit(embed=embed) await prompt.add_reaction('✅') await prompt.add_reaction('❌') reaction, reactor = await self.client.wait_for( 'reaction_add', check=check_react) if reaction.emoji == '✅': warning = 'inappropriate or obscene language' database.add_warning(message.author, warning, self.client.user) try: msg = f'You have received a warning from an administrator or mod in {message.guild.name} for the ' \ f'following content\n' \ f'> "{message.content}"' await message.author.send( embed=tools.single_embed_neg(msg)) except discord.Forbidden: msg = f'{message.author.mention} has been given a warning for inappropriate language.' await message.channel.send( embed=tools.single_embed_neg(msg)) # remove confirmation dialogue embed.remove_field(1) embed.remove_field(0) warn = f'{message.author.display_name} was issued a warning by {reactor.display_name}' embed.add_field(name='Action', value=warn, inline=False) await prompt.edit(embed=embed) await prompt.clear_reactions() try: await message.delete() except discord.NotFound: pass break elif reaction.emoji == '❌': embed.remove_field(1) embed.remove_field(0) await prompt.clear_reactions() # ignore elif reaction.emoji == options[2]: embed.remove_field(1) embed.remove_field(0) embed.add_field( name='Action', value= f'{message.author.display_name}\'s message was ignored by {reactor.display_name}', inline=False) await prompt.edit(embed=embed) await prompt.clear_reactions() break elif reaction.emoji == options[3]: try: msg = f'Your message was deleted by a mod or admin for inappropriate content.\n' \ f'Your original message: "{message.content}"' await message.author.send( embed=tools.single_embed_neg(msg)) except discord.Forbidden: msg = f'{message.author.mention} one of your messages was deleted by a mod or admin for ' \ f'inappropriate content."' await message.channel.send( embed=tools.single_embed_neg(msg)) embed.remove_field(1) embed.remove_field(0) deleted = f'{message.author.display_name}\'s message was deleted by {reactor.display_name}' embed.add_field(name='Action', value=deleted, inline=False) await prompt.edit(embed=embed) await prompt.clear_reactions() try: await message.delete() except discord.NotFound: pass break # ignore links created by moderators if message.author.guild_permissions.create_instant_invite: return # ignore this guild's invites for w in message.content.split(' '): try: if w in [ f'discord.gg/{invite.code}' for invite in await message.guild.invites() ]: pass except discord.HTTPException as e: print(e) # if link found, delete and warn if 'discord.gg/' in message.content and 'discord.gg/stalkmarket' not in message.content: try: await message.delete() except discord.NotFound: pass except Exception as e: print(f'Could not delete discord.gg message {message}: {e}') msg = f'Advertising other Discord servers is not allowed.' database.add_warning(message.author, msg, self.client.user) fmt = f'You have received an automatic warning for posting a Discord link in ' \ f'**{message.guild.name}**.\n> "{msg}"' try: # try to DM the warning to the user await message.author.send(embed=tools.single_embed_neg(fmt)) except discord.Forbidden: # warn publicly if DMs are closed await message.channel.send(embed=tools.single_embed_neg(fmt)) await self.check_warnings(message) te_links = [ 'https://turnip.exchange', 'http://turnip.exchange', 'turnip.exchange/island' ] content = [w for w in message.content.split(' ')] if any(x in te_links for x in content): try: await message.delete() except discord.NotFound: pass except Exception as e: print( f'Could not delete turnip.exchange message {message}: {e}') msg = f'Advertising Turnip Exchange links is not allowed.' database.add_warning(message.author, msg, self.client.user) fmt = f'You have received an automatic warning for posting a Turnip Exchange link in ' \ f'**{message.guild.name}**.\n> "{msg}"' try: # try to DM the warning to the user await message.author.send(embed=tools.single_embed_neg(fmt)) except discord.Forbidden: # warn publicly if DMs are closed await message.channel.send(embed=tools.single_embed_neg(fmt)) await self.check_warnings(message) blacklist = database.get_blacklist(message.guild) for b in blacklist: if b in message.content.lower(): try: await message.delete() msg = f'You have entered a blacklisted link in **{message.guild.name}** ' \ f'Your message has been deleted.' try: await message.author.send( embed=tools.single_embed_neg(msg)) except discord.Forbidden: await message.channel.send( embed=tools.single_embed_neg(msg)) except discord.NotFound as e: print(e)
async def art_lookup(self, ctx, *, query=None): credit = discord.utils.get(ctx.guild.members, id=272151652344266762) embeds = [] if query is not None: # real art async with aiohttp.ClientSession() as session: url = f'http://157.245.28.81/artwork/real/{query}' f, status = await self.fetch(session, url) if status != 200 or len(f) < 1: await ctx.send(embed=tools.single_embed_neg( f'Could not find art \"{query}\"!')) return real = json.loads(f) title = real['name'] description = f'Buy: {real["buy"]} bells, Sell: {real["sell"]} bells' embed = discord.Embed(title=f'{title} (real)', description=description, color=discord.Color.green()) embed.add_field(name='Name', value=real["realArtworkTitle"], inline=False) embed.add_field(name='Artist', value=real["artist"], inline=False) embed.add_field(name='Description', value=real["museumDescription"], inline=False) embed.set_image( url= f'http://williamspires.co.uk:9876/Furniture/{real["filename"]}.png' ) embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embeds.append(embed) # fake art async with aiohttp.ClientSession() as session: url = f'http://157.245.28.81/artwork/fake/{query}' f, status = await self.fetch(session, url) try: fake = json.loads(f) title = fake['name'] description = f'Buy: {fake["buy"]} bells, Sell: {fake["sell"]} bells' embed = discord.Embed(title=f'{title} (fake)', description=description, color=discord.Color.green()) embed.add_field(name='Name', value=fake["realArtworkTitle"], inline=False) embed.add_field(name='Artist', value=fake["artist"], inline=False) embed.add_field(name='Description', value=fake["museumDescription"], inline=False) embed.set_image( url= f'http://williamspires.co.uk:9876/Furniture/{fake["filename"]}.png' ) embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})' ) embeds.append(embed) except json.JSONDecodeError: pass else: async with aiohttp.ClientSession() as session: url = 'http://157.245.28.81/artwork/all/real' f, status = await self.fetch(session, url) real = json.loads(f) real_art = [] title = 'Art' count = 1 for art in real: if len(real_art) == 20: real_art = '\n'.join(real_art) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name=f'Part {count}', value=f'```\n{real_art}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})' ) embeds.append(embed) real_art = [] count += 1 else: art_name = art["realArtworkTitle"] if len(art_name) > 30: art_name = art_name[:30] + '...' real_art.append( f'{art["name"]} {"." * (25 - len(art["name"]))} {art_name}' ) if len(real_art) > 0: real_art = '\n'.join(real_art) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name=f'Part {count}', value=f'```\n{real_art}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embeds.append(embed) paginator = BotEmbedPaginator(ctx, embeds) await paginator.run()
async def fish_lookup(self, ctx, *, query): credit = discord.utils.get(ctx.guild.members, id=272151652344266762) month = await self.fix_capitalize(query) embeds = [] # collect all insect data for selected month if month in months: async with aiohttp.ClientSession() as session: url = f'{will_url}/fish/available/{month}' f, status = await self.fetch(session, url) if status != 200 or len(f) < 1: await ctx.send(embed=tools.single_embed_neg( f'Could not find month \"{month}\"!')) return fish_raw = json.loads(f) url = f'{will_url}/fish/leaving/{month}/NH' f, status = await self.fetch(session, url) if status != 200 or len(f) < 1: await ctx.send(embed=tools.single_embed_neg( f'Could not find month \"{month}\"!')) return fish_leaving_nh = json.loads(f) url = f'{will_url}/fish/leaving/{month}/SH' f, status = await self.fetch(session, url) if status != 200 or len(f) < 1: await ctx.send(embed=tools.single_embed_neg( f'Could not find month \"{month}\"!')) return fish_leaving_sh = json.loads(f) nh_fish = [k for k in fish_raw if k['nh' + month[:3]] != 'NA'] title = f'{month} (Northern Hemisphere)' fish_list = [] count = 1 for fish in nh_fish: if len(fish_list) == 25: fish_list = '\n'.join(fish_list) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name=f'Fish Part {count}', value=f'```\n{fish_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})' ) embeds.append(embed) fish_list = [] count += 1 else: fish_list.append( f'{fish["name"]} {"." * (20 - len(fish["name"]))} {fish["nh" + month[:3]]}' ) if len(fish_list) > 0: fish_list = '\n'.join(fish_list) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name=f'Fish Part {count}', value=f'```\n{fish_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embeds.append(embed) count += 1 nh_fish_leaving = [k['name'] for k in fish_leaving_nh] if len(nh_fish_leaving) > 0: fish_list = '\n'.join(nh_fish_leaving) embed = discord.Embed( title=f'{title}\nFish Leaving Next Month', color=discord.Color.green()) embed.add_field(name=f'Fish Part {count}', value=f'```\n{fish_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embeds.append(embed) sh_fish = [k for k in fish_raw if k['sh' + month[:3]] != 'NA'] title = f'{month} (Southern Hemisphere)' fish_list = [] count = 1 for fish in sh_fish: if len(fish_list) == 25: fish_list = '\n'.join(fish_list) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name=f'Fish Part {count}', value=f'```\n{fish_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})' ) embeds.append(embed) fish_list = [] count += 1 else: fish_list.append( f'{fish["name"]} {"." * (20 - len(fish["name"]))} {fish["sh" + month[:3]]}' ) if len(fish_list) > 0: fish_list = '\n'.join(fish_list) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name=f'Fish Part {count}', value=f'```\n{fish_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embeds.append(embed) count += 1 sh_fish_leaving = [k['name'] for k in fish_leaving_sh] if len(nh_fish_leaving) > 0: fish_list = '\n'.join(sh_fish_leaving) embed = discord.Embed( title=f'{title}\nFish Leaving Next Month', color=discord.Color.green()) embed.add_field(name=f'Fish Part {count}', value=f'```\n{fish_list}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embeds.append(embed) else: async with aiohttp.ClientSession() as session: url = f'{will_url}/fish/{query.lower()}' f, status = await self.fetch(session, url) if status != 200 or len(f) < 1: await ctx.send(embed=tools.single_embed_neg( f'Could not find insect \"{query}\"!')) return data = json.loads(f) thumbnail = f'{image}Fish/{data["critterpediaFilename"]}.png' description = f'```\n' \ f'Value: {data["sell"]} bells\n' \ f'Where: {data["whereOrHow"]}\n' \ f'Shadow: {data["shadow"]}```' embed = discord.Embed(title=data['name'].capitalize(), description=description, color=discord.Color.green()) nh_availability = '\n'.join([ f'{k[2:]} {"." * 5} {v}' for k, v in data.items() if v != 'NA' and k.startswith('nh') ]) embed.add_field(name='Northern Hemisphere Availability', value=f'```\n{nh_availability}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embed.set_image(url=thumbnail) embeds.append(embed) embed = discord.Embed(title=data['name'].capitalize(), description=description, color=discord.Color.green()) sh_availability = '\n'.join([ f'{k[2:]} {"." * 5} {v}' for k, v in data.items() if v != 'NA' and k.startswith('sh') and k != 'shadow' ]) embed.add_field(name='Southern Hemisphere Availability', value=f'```\n{sh_availability}```') embed.set_footer( text=f'API courtesy of {credit.display_name} ({credit})') embed.set_image(url=thumbnail) embeds.append(embed) paginator = BotEmbedPaginator(ctx, embeds) await paginator.run()
async def slot(self, ctx, bet=10): if bet < 1: await ctx.send(embed=tools.single_embed_neg(f'You cannot bet less than 1 bell.')) return await self.add_to_economy(ctx.author) bells = await self.get_bells(ctx.author) if bells <= 0: await ctx.send(embed=tools.single_embed_neg(f'You do not have enough bells to play!')) return elif bells < bet: await ctx.send(embed=tools.single_embed_neg(f'Your bet is more than your total bells!')) return await self.modify_bells(ctx.author, bet * -1) bells = await self.get_bells(ctx.author) fruits = [':watermelon:', ':grapes:', ':strawberry:', ':cherries:', ':pineapple:', ':peach:', ':coconut:', ':kiwi:', ':banana:'] slots = self.client.get_emoji(714813946984398909) slot1 = fruits[random.randint(0, 8)] slot2 = fruits[random.randint(0, 8)] slot3 = fruits[random.randint(0, 8)] if bet == 1: title = f'{ctx.author.display_name} bet {bet} bell!' else: title = f'{ctx.author.display_name} bet {bet} bells!' winning_scenarios = f'� x3 ........................ Win 10x!\n' \ f'Match all 3 .............. Win 4x!\n' \ f'Match any 2 ............ Win 2x!' embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name='\u200b', value=f'{slots}') embed.add_field(name='\u200b', value=f'{slots}') embed.add_field(name='\u200b', value=f'{slots}') embed.add_field(name='How to Win', value=winning_scenarios) embed.add_field(name='Balance', value=f'{bells} bells', inline=False) output = await ctx.send(embed=embed) await asyncio.sleep(1) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name='\u200b', value=f'{slot1}') embed.add_field(name='\u200b', value=f'{slots}') embed.add_field(name='\u200b', value=f'{slots}') embed.add_field(name='How to Win', value=winning_scenarios) embed.add_field(name='Balance', value=f'{bells} bells', inline=False) await output.edit(embed=embed) await asyncio.sleep(1) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name='\u200b', value=f'{slot1}') embed.add_field(name='\u200b', value=f'{slot2}') embed.add_field(name='\u200b', value=f'{slots}') embed.add_field(name='How to Win', value=winning_scenarios) embed.add_field(name='Balance', value=f'{bells} bells', inline=False) await output.edit(embed=embed) await asyncio.sleep(1) embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name='\u200b', value=f'{slot1}') embed.add_field(name='\u200b', value=f'{slot2}') embed.add_field(name='\u200b', value=f'{slot3}') embed.add_field(name='How to Win', value=winning_scenarios) embed.add_field(name='Balance', value=f'{bells} bells', inline=False) await output.edit(embed=embed) jackpot = False if all([slot1, slot2, slot3]) == ':cherry:': winnings = int(bet * 10) jackpot = True elif all([slot1, slot2]) == slot3: winnings = int(bet * 4) elif slot1 == slot2 or slot1 == slot3 or slot2 == slot3: winnings = int(bet * 2) else: winnings = bet * 0 await self.modify_bells(ctx.author, winnings) if int(winnings) > 0: bells = await self.get_bells(ctx.author) msg = f'You\'ve won **{winnings}** bells!' embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name='\u200b', value=f'{slot1}') embed.add_field(name='\u200b', value=f'{slot2}') embed.add_field(name='\u200b', value=f'{slot3}') embed.add_field(name='How to Win', value=winning_scenarios) embed.add_field(name='Balance', value=f'{bells} bells', inline=False) if jackpot: dance = self.client.get_emoji(715295817681993759) embed.add_field(name='JACKPOT!', value=f'{dance} {msg} {dance}', inline=False) else: embed.add_field(name='Winner!', value=f'{slots} {msg} {slots}', inline=False) await output.edit(embed=embed) else: bells = await self.get_bells(ctx.author) msg = f'Better luck next time!' embed = discord.Embed(title=title, color=discord.Color.green()) embed.add_field(name='\u200b', value=f'{slot1}') embed.add_field(name='\u200b', value=f'{slot2}') embed.add_field(name='\u200b', value=f'{slot3}') embed.add_field(name='How to Win', value=winning_scenarios, inline=False) embed.add_field(name='Balance', value=f'{bells} bells', inline=False) embed.add_field(name='No matches', value=msg, inline=False) await output.edit(embed=embed)
async def cast(self, ctx): bells = await self.get_bells(ctx.author) if bells < 10: await ctx.send(embed=tools.single_embed_neg('You do not have enough bells to buy bait!')) return await self.modify_bells(ctx.author, -10) await self.add_collection_fish(ctx.author) title = 'You bought some fish bait for 10 bells!' async with aiohttp.ClientSession() as session: if random.randint(0, 5) == 0: f = await self.fetch(session, will_url + 'fish/sea%20bass') data = json.loads(f) if await self.check_collection_fish(ctx.author, data['name']): msg = f':x: You\'ve already caught: **{data["name"]}**! *COMMON*' else: await self.update_collection_fish(ctx.author, data['name']) msg = f'You caught: **{data["name"]}**! *COMMON*' thumbnail = f'{image}Fish/{data["critterpediaFilename"]}.png' embed = discord.Embed(title=title, description=msg, color=discord.Color.green()) embed.set_image(url=thumbnail) await ctx.send(embed=embed) return else: f = await self.fetch(session, will_url + 'fish/available/' + datetime.now().strftime("%B")) data = json.loads(f) fish = [[k['name'], k["critterpediaFilename"], k['spawnRate']] for k in data] verify = False while not verify: try: caught = fish[random.randint(0, len(fish))] spawn = caught[2][0].split('-')[-1] # 5% chance if int(spawn) <= 2: check = random.randint(0, 20) if check == 0: if await self.check_collection_fish(ctx.author, caught[0]): msg = f':x: You\'ve already caught: **{caught[0]}**! *RARE*' else: await self.update_collection_fish(ctx.author, caught[0]) msg = f'You caught: **{caught[0]}**! *RARE*' thumbnail = f'{image}Fish/{caught[1]}.png' embed = discord.Embed(title=title, description=msg, color=discord.Color.purple()) embed.set_image(url=thumbnail) await ctx.send(embed=embed) verify = True # 10% chance elif 2 < int(spawn) <= 5: check = random.randint(0, 10) if check == 0: if await self.check_collection_fish(ctx.author, caught[0]): msg = f':x: You\'ve already caught: **{caught[0]}**! *UNCOMMON*' else: await self.update_collection_fish(ctx.author, caught[0]) msg = f'You caught: **{caught[0]}**! *UNCOMMON*' thumbnail = f'{image}Fish/{caught[1]}.png' embed = discord.Embed(title=title, description=msg, color=discord.Color.blue()) embed.set_image(url=thumbnail) await ctx.send(embed=embed) verify = True else: if await self.check_collection_fish(ctx.author, caught[0]): msg = f':x: You\'ve already caught: **{caught[0]}**! *COMMON*' else: await self.update_collection_fish(ctx.author, caught[0]) msg = f'You caught: **{caught[0]}**! *COMMON*' thumbnail = f'{image}Fish/{caught[1]}.png' embed = discord.Embed(title=title, description=msg, color=discord.Color.green()) embed.set_image(url=thumbnail) await ctx.send(embed=embed) verify = True except IndexError: pass
async def karma_cog_on(ctx): if database.karma_cog(ctx.guild): return True msg = f'**Karma** is not turned on' await ctx.send(embed=tools.single_embed_neg(msg)) return False
async def on_command_error(self, ctx, error): if isinstance(error, commands.CommandOnCooldown): retry_after = tools.display_time(error.retry_after) await ctx.send(embed=tools.single_embed_neg(f'You can only gather once per day! Try again in {retry_after}'))
async def on_command_error(self, ctx, error): if isinstance(error, commands.CommandOnCooldown): await ctx.send(embed=tools.single_embed_neg(error))