async def all_entries(self, ctx: utils.Context, *table_names: str): base_query = """ SELECT name FROM {0} """ formatted_query = "UNION".join( base_query.format(table_name) for table_name in table_names) query = f""" SELECT DISTINCT name FROM ( {formatted_query} ) AS a ORDER BY name; """ results = [ f'{index}: {name}' for index, (name, ) in enumerate(await ctx.pool.fetch(query), 1) ] try: paginator = utils.EmbedPaginator(ctx, entries=results, per_page=15) paginator.embed.colour = 0x738bd7 await paginator.paginate() except Exception as e: await ctx.send(e)
async def queue(self, ctx): """Shows the current queue.""" vc = ctx.voice_client if vc is None: return await ctx.send('Not in a voice channel.') if not vc.is_playing() and not vc.is_paused(): return await ctx.send('Not currently playing anything.') queue = self.get_queue(ctx.guild).songs if len(queue) == 0: return await ctx.invoke(self.playing) songs = [ f'[{song.entry.title}]({song.entry.url})\nRequested by {song.requester}' for song in queue ] try: paginator = utils.EmbedPaginator(ctx, entries=songs, per_page=10) paginator.embed.colour = 0x738bd7 paginator.embed.title = f'Currently Playing {vc.source.entry.title} requested by {vc.source.requester}' paginator.embed.url = vc.source.entry.url await paginator.paginate() except Exception as e: await ctx.send(e)
async def search_entries(self, ctx: utils.Context, name: str, *table_names, type_name: str): base_query = """ SELECT name, SIMILARITY(name, $1) FROM {0} WHERE name % $1 """ formatted_query = "UNION".join( base_query.format(table_name) for table_name in table_names) query = f""" SELECT DISTINCT name, similarity FROM ( {formatted_query} ) AS a ORDER BY similarity DESC; """ results = [ f'{index}: {name}' for index, (name, _) in enumerate(await ctx.pool.fetch(query, name), 1) ] if not results: return await ctx.send(f'{type_name} not found.') try: paginator = utils.EmbedPaginator(ctx, entries=results, per_page=15) paginator.embed.colour = 0x738bd7 await paginator.paginate() except Exception as e: await ctx.send(e)
async def star_who(self, ctx, message_id: int): query = """ SELECT ARRAY( SELECT starrers.author_id FROM starboard_entries JOIN starrers ON starboard_entries.message_id=starrers.message_id WHERE starboard_entries.guild_id=$1 AND (starboard_entries.message_id=$2 OR starboard_entries.bot_message_id=$2) ); """ member_ids = await ctx.pool.fetchval(query, ctx.guild.id, message_id) if member_ids is None: return await ctx.send('This message has not been starred.') members = list( map(str, filter(None, map(ctx.guild.get_member, member_ids)))) base = utils.plural('star', len(member_ids)) if len(member_ids) > len(members): base += f' ({len(member_ids) - len(members)} left server)' try: paginator = utils.EmbedPaginator(ctx, entries=members, per_page=20) paginator.embed.title = base await paginator.paginate() except Exception as e: await ctx.send(e)
async def changelog(self, ctx): """Shows recent changes made to the bot.""" changes = await self.get_recent_changes() try: paginator = utils.EmbedPaginator(ctx, entries=changes.split('\n')) paginator.embed.title = 'Change Log' await paginator.paginate() except Exception as e: await ctx.send(e)
async def maps_(ctx, player): """Views all maps that you can travel to. This wont show maps that are not nearby.""" pg = utils.EmbedPaginator() for _map in player.map.nearby: embed = discord.Embed(color=_map._raw['colour'], description=_map.description) embed.set_author(name=_map.name) embed.add_field(name="ID", value=str(_map.id)) embed.add_field(name="Density", value=str(_map.density)) pg.add_page(embed) inf = utils.EmbedInterface(ctx.bot, pg, ctx.author) await inf.send_to(ctx) return inf.message
async def queue(self, ctx): """Shows the current queue.""" player = ctx.player if len(player.queue) == 0: return await ctx.send('There\'s nothing in the queue! Why not queue something?') songs = [f'{i}: [{track.title}]({track.uri})\nRequested by {track.requester}' for i, track in enumerate(player.queue, 1)] try: paginator = utils.EmbedPaginator(ctx, entries=songs, per_page=10) paginator.embed.colour = 0x738bd7 await paginator.paginate() except Exception as e: await ctx.send(e)
async def tag_all(self, ctx): """Lists all server-specific tags for this server.""" query = 'SELECT name FROM tags WHERE location_id=$1 ORDER BY name;' records = await ctx.pool.fetch(query, ctx.guild.id) if records: entries = [ f'{index}: {record[0]}' for index, record in enumerate(records, 1) ] try: paginator = utils.EmbedPaginator(ctx, entries=entries) await paginator.paginate() except Exception as e: await ctx.send(e) else: await ctx.send('This server has no server-specific tags.')
async def all_(self, ctx): """View all maps, regardless if they are nearby.""" pg = utils.EmbedPaginator() for _map in self.maps: if _map.id in self._ignore: continue embed = discord.Embed(color=_map._raw['colour'], description=_map.description) embed.set_author(name=_map.name + (' (Safe)' if _map.is_safe else '')) embed.add_field(name="ID", value=str(_map.id)) embed.add_field(name="Density", value=str(_map.density)) embed.add_field(name="Nearby Maps", value="`" + "`, `".join(map(str, _map.nearby)) + "`", inline=False) pg.add_page(embed) inf = utils.EmbedInterface(self.bot, pg, ctx.author) await inf.send_to(ctx)
async def tag_list(self, ctx, *, member: discord.Member = None): """Lists all the tags that belong to you or someone else.""" member = member or ctx.author query = 'SELECT name FROM tags WHERE location_id=$1 AND owner_id=$2 ORDER BY name;' records = await ctx.pool.fetch(query, ctx.guild.id, member.id) if records: entries = [ f'{index}: {record[0]}' for index, record in enumerate(records, 1) ] try: paginator = utils.EmbedPaginator(ctx, entries=entries) paginator.embed.set_author(name=member.display_name, icon_url=member.avatar_url) await paginator.paginate() except Exception as e: await ctx.send(e) else: await ctx.send(f'{member.display_name} has no tags.')
async def blades(self, ctx, *, member: discord.Member = None): """Shows a user's current Rare Blades.""" member = member or ctx.author query = """ SELECT ARRAY_AGG(blade) FROM pulled_blades WHERE user_id=$1 AND common IS FALSE; """ blades = await ctx.pool.fetchval(query, member.id) if blades is None: return await ctx.send(f'{member.display_name} has no Rare Blades.') try: paginator = utils.EmbedPaginator(ctx, entries=blades, per_page=15) paginator.embed.colour = 0x738bd7 await paginator.paginate() except Exception as e: await ctx.send(e)
async def explored(self, ctx): """Views all the maps you have explored.""" player = self.bot.player_manager.get_player(ctx.author) if not player: return await ctx.send( f"You don't have a player! {blobs.BLOB_PLSNO} Create one with `{ctx.prefix}create`!" ) pg = utils.EmbedPaginator() for _map in player.explored_maps: embed = discord.Embed(colour=_map._raw['colour'], description=_map.description) embed.set_author(name=_map.name + (' (Safe)' if _map.is_safe else '')) embed.add_field(name="ID", value=str(_map.id)) embed.add_field(name="Density", value=str(_map.density)) embed.add_field(name="Nearby Maps", value="`" + "`, `".join(map(str, _map.nearby)) + "`", inline=False) pg.add_page(embed) inf = utils.EmbedInterface(self.bot, pg, ctx.author) await inf.send_to(ctx)
async def tag_search(self, ctx, *, name: str): """Searches for a tag.""" query = """ SELECT name FROM tags WHERE location_id=$1 AND name % $2 ORDER BY similarity(name, $2) DESC; """ records = await ctx.pool.fetch(query, ctx.guild.id, name) if records: entries = [ f'{index}: {record[0]}' for index, record in enumerate(records, 1) ] try: paginator = utils.EmbedPaginator(ctx, entries=entries) await paginator.paginate() except Exception as e: await ctx.send(e) else: await ctx.send('No tags found.')
async def realmeye(self, ctx, member: utils.MemberLookupConverter = None): if not member: member = ctx.author udata = await sql.get_user(self.client.pool, member.id) if not udata: return await ctx.send( "The specified user was not found in the database!") ign = udata[sql.usr_cols.ign] embed = discord.Embed( title="Fetching...", description= "Please wait while your player-data is being retrieved.\nThis can take up to a minute if realmeye's servers are " "being slow! (They usually are)", color=discord.Color.orange()) embed.set_thumbnail(url="https://i.imgur.com/nLRgnZf.gif") msg = await ctx.send(embed=embed) try: async with aiohttp.ClientSession( timeout=aiohttp.ClientTimeout(10)) as cs: async with cs.get( f'https://nightfirec.at/realmeye-api/?player={ign}' ) as r: if r.status == 403: print("ERROR: API ACCESS FORBIDDEN") await ctx.send( f"<@{self.client.owner_id}> ERROR: API ACCESS REVOKED!." ) data = await r.json() # returns dict if not data: try: await msg.delete() except discord.NotFound: pass return await ctx.send( "There was an issue retrieving realmeye data. Please try the command later." ) if 'error' in data: try: await msg.delete() except discord.NotFound: pass embed = discord.Embed( title='Error!', description= f"There were no players found on realmeye with the name `{ign}`.", color=discord.Color.red()) return await ctx.send(embed=embed) except asyncio.TimeoutError: try: await msg.delete() except discord.NotFound: pass return await ctx.send( "There was an issue retrieving realmeye data. Please try the command later." ) d = f"{member.mention}\n" d += f"**{data['desc1']}**\n" if data['desc1'] else "" d += f"{data['desc2']}\n" if data['desc2'] else "" d += f"{data['desc3']}\n" if data['desc3'] else "" d += f"\n\nGuild: [{data['guild']}](https://www.realmeye.com/guild/{data['guild'].replace(' ', '%20')}) ({data['guild_rank']})" if data[ 'guild'] else "" base_embed = discord.Embed( title=f"Realmeye Info for {ign}", description=d, url=f'https://www.realmeye.com/player/{ign}', color=discord.Color.blue()) info = f"Characters: **{data['chars']}**\nSkins: **{data['skins']}**\nFame: **{data['fame']:,}**<:fame:682209281722024044>\nEXP: **{data['exp']:,}**\nStars: **" \ f"{data['rank']}**⭐\n\nAccount Fame: **{data['account_fame']:,}**<:fame:682209281722024044>\n" info += f"Created: {data['created']}" if 'created' in data else f"First Seen: {data['player_first_seen']}" if 'player_first_seen' in data else "" info += f"\nLast Seen: {data['player_last_seen']}\nCharacters Hidden: {'✅' if data['characters_hidden'] else '❌'}" if not data['characters_hidden'] and data['characters']: base_embed.add_field( name="Info", value=info + "\n\nCharacter Data continues on the next page...", inline=False) base_embed.set_footer( text='© Darkmattr | Use the reactions to flip pages', icon_url=member.avatar_url) with open('data/itemImages.json') as file: item_images = json.load(file) with open('data/skinImages.json') as file: skin_images = json.load(file) with open('data/createdItemImages.json') as file: created_images: dict = json.load(file) embeds = [] embeds.append(base_embed) for c in data['characters']: embed = discord.Embed( title=f"Characters of {ign}: {c['class']}", color=discord.Color.teal()) ids = [ c['equips']['data_weapon_id'], c['equips']['data_ability_id'], c['equips']['data_armor_id'], c['equips']['data_ring_id'] ] i_str = "-".join([str(id) for id in ids]) if i_str in created_images: i_url = created_images[i_str] else: i_url = await make_equips_img(ids, item_images) created_images[i_str] = i_url with open('data/createdItemImages.json', 'w') as file: json.dump(created_images, file) embed.set_image(url=i_url) embed.set_thumbnail(url=skin_images[str(c['data_class_id'])][ str(c['data_skin_id'])]) desc = f"Class Quests: **{c['cqc']}/5** Quests\nEXP: **{c['exp']:,}**xp\nLevel: **{c['level']}**\nStats Maxed: " \ f"**{c['stats_maxed']}/8**\nPlace: **{c['place']:,}**\nBackpack: " desc += "✅" if c['backpack'] else "❌" desc += "\nPet: " desc += f"✅\nPet Name: {c['pet']}" if c['pet'] else "❌" embed.description = desc stat_d = c['stats'] hp_bar = utils.textProgressBar(stat_d['hp'], max_stats[c['class']][0], decimals=0, prefix='', percent_suffix=" Maxed", suffix="", length=12, fullisred=False) mp_bar = utils.textProgressBar(stat_d['mp'], max_stats[c['class']][1], decimals=0, prefix='', percent_suffix=" Maxed", suffix="", length=12, fullisred=False) att_bar = utils.textProgressBar(stat_d['attack'], max_stats[c['class']][2], decimals=0, prefix='', percent_suffix=" Maxed", suffix="", length=6, fullisred=False) def_bar = utils.textProgressBar(stat_d['defense'], max_stats[c['class']][3], decimals=0, prefix='', percent_suffix=" Maxed", suffix="", length=6, fullisred=False) spd_bar = utils.textProgressBar(stat_d['speed'], max_stats[c['class']][4], decimals=0, prefix='', percent_suffix=" Maxed", suffix="", length=6, fullisred=False) dex_bar = utils.textProgressBar(stat_d['dexterity'], max_stats[c['class']][5], decimals=0, prefix='', percent_suffix=" Maxed", suffix="", length=6, fullisred=False) vit_bar = utils.textProgressBar(stat_d['vitality'], max_stats[c['class']][6], decimals=0, prefix='', percent_suffix=" Maxed", suffix="", length=6, fullisred=False) wis_bar = utils.textProgressBar(stat_d['wisdom'], max_stats[c['class']][7], decimals=0, prefix='', percent_suffix=" Maxed", suffix="", length=6, fullisred=False) hp_s = f"HP: **{stat_d['hp']}/{max_stats[c['class']][0]}**\n{hp_bar}\n" \ f"MP: **{stat_d['mp']}/{max_stats[c['class']][1]}**\n{mp_bar}\n" stat_s_1 = f"ATT: **{stat_d['attack']}/{max_stats[c['class']][2]}** | {att_bar}\n" \ f"DEF: **{stat_d['defense']}/{max_stats[c['class']][3]}** | {def_bar}\n" \ f"SPD: **{stat_d['speed']}/{max_stats[c['class']][4]}** | {spd_bar}\n" stat_s_2 = f"DEX: **{stat_d['dexterity']}/{max_stats[c['class']][5]}** | {dex_bar}\n" \ f"VIT: **{stat_d['vitality']}/{max_stats[c['class']][6]}** | {vit_bar}\n" \ f"WIS: **{stat_d['wisdom']}/{max_stats[c['class']][7]}** | {wis_bar}" embed.add_field(name="Health & Mana", value=hp_s, inline=False) embed.add_field(name="Stats:", value=stat_s_1, inline=False) embed.add_field(name="More Stats:", value=stat_s_2) embed.set_footer( text='© Darkmattr | Use the reactions to flip pages') embeds.append(embed) paginator = utils.EmbedPaginator(self.client, ctx, embeds) try: await msg.delete() except discord.NotFound: pass return await paginator.paginate() base_embed.add_field(name="Info", value=info, inline=False) await msg.edit(embed=base_embed)
async def parsemembers(self, ctx): if not ctx.message.attachments: return await ctx.send( "Please attach an image containing only the result of the /who command!", delete_after=10) if len(ctx.message.attachments) > 1: return await ctx.send("Please only attach 1 image.", delete_after=10) attachment = ctx.message.attachments[0] if not attachment.height or 'mp4' in attachment.filename.lower( ) or 'mov' in attachment.filename.lower(): return await ctx.send( "Please only attach an image of type 'png' or 'jpg'.", delete_after=10) image = io.BytesIO() await attachment.save(image, seek_begin=True) if ctx.author.voice: vcchannel = ctx.author.voice.channel else: setup = VCSelect(self.client, ctx, parse=True) data = await setup.start() if isinstance(data, tuple): (raidnum, inraiding, invet, inevents, raiderrole, rlrole, hcchannel, vcchannel, setup_msg) = data else: return await setup_msg.delete() msg: discord.Message = await ctx.send( "Parsing image. This may take a minute...") res = await self.client.loop.run_in_executor( None, functools.partial(parse_image, ctx.author, image, vcchannel, True)) if not res: embed = discord.Embed( title="Error!", description= "Could not find the who command in the image you provided.\nPlease re-run the " "command with an image that shows the results of `/who`.", color=discord.Color.red()) await msg.delete() return await ctx.send(embed=embed) crashing, possible_alts, fixed_names = res await msg.edit(content="Parsing members. Please wait...") n_crashers = len(crashing) crashing_members = [] converter = utils.MemberLookupConverter() pages = [] nm_crashing = [] crashing_players = [] for n in crashing: try: mem = await converter.convert(ctx, n) except discord.ext.commands.BadArgument: crashing_players.append(n) for m in crashing_members: n_suspensions = 0 active_suspension = "❌" pdata = await sql.get_users_punishments(self.client.pool, m.id, ctx.guild.id) bdata = await sql.get_blacklist(self.client.pool, m.id, ctx.guild.id) pembed = discord.Embed( description= f"**Punishment Log for {m.mention}** - `{m.display_name}`") if pdata: for i, r in enumerate(pdata, start=1): requester = ctx.guild.get_member(r[sql.punish_cols.r_uid]) active = "✅" if r[sql.punish_cols.active] else "❌" starttime = f"Issued at: `{r[sql.punish_cols.starttime].strftime('%b %d %Y %H:%M:%S')}`" endtime = f"\nEnded at: `{r[sql.punish_cols.endtime].strftime('%b %d %Y %H:%M:%S')}`" if r[ sql.punish_cols.endtime] else "" ptype = r[sql.punish_cols.type].capitalize() pembed.add_field( name=f"{ptype} #{i} | Active {active}", value= f"Issued by: {requester.mention if requester else '(Issuer left server)'}\nReason:\n{r[sql.punish_cols.reason]}\n{starttime}\n" f"{endtime}", inline=False) if r[sql.punish_cols.active] and ptype == 'Suspend': active_suspension = active if ptype == 'Suspend': n_suspensions += 1 if bdata: for i, r in enumerate(bdata, start=1): requester = ctx.guild.get_member(r[sql.blacklist_cols.rid]) active = "✅" starttime = f"Issued at: `{r[sql.blacklist_cols.issuetime].strftime('%b %d %Y %H:%M:%S')}`" btype = r[sql.blacklist_cols.type].capitalize() pembed.add_field( name= f"{btype} #{i} issued by {requester.mention if requester else '(Issuer left server)'} | Active {active}", value= f"Reason:\n{r[sql.punish_cols.reason]}\n{starttime}") if pdata or bdata: pembed.description += f"\nFound `{len(pdata)}` Punishments in this user's history.\nFound `{len(bdata)}` Blacklists in this users history." pages.append(pembed) nm_crashing.append((m, n_suspensions, active_suspension)) mstring = "" nm_crashing = sorted(nm_crashing, key=lambda x: x[1], reverse=True) for r in nm_crashing: mstring += f"{r[0].mention} **-** `{r[0].display_name}`\nSuspensions: **{r[1]}** | Active: {r[2]}\n" if not mstring: mstring = "No members crashing!" embed = discord.Embed( title=f"Parsing Results for {vcchannel.name}", description=f"Possible Crashers: **{n_crashers}**", color=discord.Color.orange()) if len(mstring) > 1024: lines = mstring.splitlines(keepends=True) curr_str = "" n_sections = 1 for l in lines: if len(l) + len(curr_str) >= 1024: embed.add_field( name= f"Members Crashing (in the server) ({n_sections}):", value=curr_str, inline=True) curr_str = l n_sections += 1 else: curr_str += l embed.add_field( name=f"Members Crashing (in the server) ({n_sections}):", value=curr_str, inline=True) else: embed.add_field(name="Members Crashing (in the server):", value=mstring, inline=True) pstring = "\n".join( crashing_players ) if crashing_players else 'No players who are not in the server crashing.' embed.add_field(name="Players Crashing (not in server):", value=pstring, inline=False) if fixed_names: fixedlist = " Fixed Name | Original Parse".join( "`/kick " + fixed + "` | (" + orig + ")\n" for (orig, fixed) in fixed_names) embed.add_field(name="Possible Fixed Names", value=fixedlist, inline=True) if possible_alts: altlist = "".join("`" + name + "`\n" for name in possible_alts) embed.add_field(name="Possible Alts (In VC but not in game)", value=altlist, inline=True) pages.insert(0, embed) await msg.delete() paginator = utils.EmbedPaginator(self.client, ctx, pages) await paginator.paginate()
async def find(self, ctx, member): if member.strip().lower() in self.defaultnames: embed = discord.Embed(title="Error!", description=f"`{member}` is a default name!", color=discord.Color.red()) return await ctx.send(embed=embed) else: member = await utils.MemberLookupConverter().convert(ctx, member) if member.voice is None: vc = '❌' else: vc = f"`{member.voice.channel.name}`" if member.nick and " | " in member.nick: # Check if user has an alt account names = member.nick.split(" | ") names = ["".join([c for c in n if c.isalpha()]) for n in names] desc = f"Found {member.mention} with the ign's: " desc += " | ".join([ '[' + ''.join([n for n in name]) + '](https://www.realmeye.com/player/' + ''.join([n for n in name]) + ")" for name in names ]) desc += f"\nVoice Channel: {vc}" desc += f"\nRealm Names: `{'`, `'.join(names)}`" else: name = ''.join([i for i in member.display_name if i.isalpha()]) desc = f"Found {member.mention} with the ign: [{name}](https://www.realmeye.com/player/{name})\nVoice Channel: {vc}" desc += f"\nRealm Name: `{name}`" embed = discord.Embed(description=desc, color=discord.Color.green()) pdata = await sql.get_users_punishments(self.client.pool, member.id, ctx.guild.id) bdata = await sql.get_blacklist(self.client.pool, member.id, ctx.guild.id) pages = [] if pdata: for i, r in enumerate(pdata, start=1): requester = ctx.guild.get_member(r[sql.punish_cols.r_uid]) active = "✅" if r[sql.punish_cols.active] else "❌" starttime = f"Issued at: `{r[sql.punish_cols.starttime].strftime('%b %d %Y %H:%M:%S')}`" endtime = f"\nEnded at: `{r[sql.punish_cols.endtime].strftime('%b %d %Y %H:%M:%S')}`" if r[ sql.punish_cols.endtime] else "" ptype = r[sql.punish_cols.type].capitalize() color = discord.Color.orange() if ptype == "Warn" else discord.Color.red() if ptype == "Suspend" else \ discord.Color.from_rgb(0, 0, 0) pembed = discord.Embed(title=f"Punishment Log #{i} - {ptype}", color=color) pembed.description = f"Punished member: {member.mention}\n**{ptype}** issued by {requester.mention if requester else '(Issuer left server)'}\nActive: {active}" pembed.add_field(name="Reason:", value=r[sql.punish_cols.reason], inline=False) pembed.add_field(name="Time:", value=starttime + endtime) pages.append(pembed) if bdata: for i, r in enumerate(bdata, start=1): requester = ctx.guild.get_member(r[sql.blacklist_cols.rid]) active = "✅" starttime = f"Issued at: `{r[sql.blacklist_cols.issuetime].strftime('%b %d %Y %H:%M:%S')}`" btype = r[sql.blacklist_cols.type].capitalize() color = discord.Color.from_rgb(0, 0, 0) bembed = discord.Embed(title=f"Blacklist Log #{i} - {btype}", color=color) bembed.description = f"Punished member: {member.mention}\n**{btype}** blacklist issued by {requester.mention if requester else '(Issuer left server)'}\nActive:" \ f" {active}" bembed.add_field(name="Reason:", value=r[sql.blacklist_cols.reason], inline=False) bembed.add_field(name="Time:", value=starttime) pages.append(bembed) if pdata or bdata: embed.add_field( name="Punishments:", value= f"Found `{len(pdata)}` Punishments in this user's history.\nFound `{len(bdata)}` Blacklists in this users history.\nUse the " "reactions below to navigate through them.") pages.insert(0, embed) paginator = utils.EmbedPaginator(self.client, ctx, pages) await paginator.paginate() else: embed.add_field(name="Punishments:", value="No punishment or blacklist logs found!") await ctx.send(embed=embed)