2016-07-09 13:27:19 +12:00
|
|
|
from discord.ext import commands
|
|
|
|
from .utils import config
|
2016-07-17 04:49:14 +12:00
|
|
|
from .utils import checks
|
2016-07-26 07:25:47 +12:00
|
|
|
import discord
|
2016-07-09 13:27:19 +12:00
|
|
|
|
2016-09-29 12:39:34 +13:00
|
|
|
|
|
|
|
class Stats:
|
|
|
|
"""Leaderboard/stats related commands"""
|
|
|
|
|
|
|
|
def __init__(self, bot):
|
|
|
|
self.bot = bot
|
|
|
|
|
|
|
|
def find_command(self, command):
|
|
|
|
cmd = None
|
2016-09-26 16:58:33 +13:00
|
|
|
|
|
|
|
for part in command.split():
|
|
|
|
try:
|
|
|
|
if cmd is None:
|
|
|
|
cmd = self.bot.commands.get(part)
|
|
|
|
else:
|
|
|
|
cmd = cmd.commands.get(part)
|
|
|
|
except AttributeError:
|
|
|
|
cmd = None
|
|
|
|
break
|
|
|
|
|
2016-09-29 12:39:34 +13:00
|
|
|
return cmd
|
2016-07-09 13:27:19 +12:00
|
|
|
|
2016-09-26 16:58:33 +13:00
|
|
|
@commands.group(no_pm=True)
|
|
|
|
@checks.custom_perms(send_messages=True)
|
|
|
|
async def command(self):
|
|
|
|
pass
|
|
|
|
|
2016-09-29 12:39:34 +13:00
|
|
|
@command.command(no_pm=True, name="stats")
|
2016-09-26 16:58:33 +13:00
|
|
|
@checks.custom_perms(send_messages=True)
|
|
|
|
async def command_stats(self, ctx, *, command):
|
|
|
|
"""This command can be used to view some usage stats about a specific command"""
|
2016-09-29 12:39:34 +13:00
|
|
|
cmd = self.find_command(command)
|
2016-09-26 16:58:33 +13:00
|
|
|
if cmd is None:
|
|
|
|
await self.bot.say("`{}` is not a valid command".format(command))
|
|
|
|
|
|
|
|
total_command_stats = await config.get('command_usage')
|
|
|
|
|
2016-07-09 13:27:19 +12:00
|
|
|
@commands.command(pass_context=True, no_pm=True)
|
2016-08-15 14:10:12 +12:00
|
|
|
@checks.custom_perms(send_messages=True)
|
2016-07-09 13:27:19 +12:00
|
|
|
async def mostboops(self, ctx):
|
|
|
|
"""Shows the person you have 'booped' the most, as well as how many times"""
|
2016-09-29 12:39:34 +13:00
|
|
|
r_filter = {'member_id': ctx.message.author.id}
|
|
|
|
boops = await config.get_content('boops', r_filter)
|
|
|
|
if boops is None:
|
2016-07-18 03:19:41 +12:00
|
|
|
await self.bot.say("You have not booped anyone {} Why the heck not...?".format(ctx.message.author.mention))
|
|
|
|
return
|
2016-09-26 16:58:33 +13:00
|
|
|
|
2016-09-29 12:39:34 +13:00
|
|
|
# Just to make this easier, just pay attention to the boops data, now that we have the right entry
|
|
|
|
boops = boops[0]['boops']
|
|
|
|
|
2016-08-16 15:30:52 +12:00
|
|
|
# First get a list of the ID's of all members in this server, for use in list comprehension
|
2016-07-29 04:59:12 +12:00
|
|
|
server_member_ids = [member.id for member in ctx.message.server.members]
|
2016-08-16 15:30:52 +12:00
|
|
|
# Then get a sorted list, based on the amount of times they've booped the member
|
|
|
|
# Reverse needs to be true, as we want it to go from highest to lowest
|
2016-09-29 14:00:41 +13:00
|
|
|
sorted_boops = sorted(boops.items(), key=lambda x: x[1], reverse=True)
|
2016-08-17 03:22:32 +12:00
|
|
|
# Then override the same list, checking if the member they've booped is in this server
|
2016-07-29 04:59:12 +12:00
|
|
|
sorted_boops = [x for x in sorted_boops if x[0] in server_member_ids]
|
2016-09-26 16:58:33 +13:00
|
|
|
|
2016-08-16 15:30:52 +12:00
|
|
|
# Since this is sorted, we just need to get the following information on the first user in the list
|
2016-09-29 14:00:41 +13:00
|
|
|
most_id, most_boops = sorted_boops[0]
|
|
|
|
|
2016-07-26 07:25:47 +12:00
|
|
|
member = discord.utils.find(lambda m: m.id == most_id, self.bot.get_all_members())
|
2016-07-18 03:19:41 +12:00
|
|
|
await self.bot.say("{0} you have booped {1} the most amount of times, coming in at {2} times".format(
|
|
|
|
ctx.message.author.mention, member.mention, most_boops))
|
2016-07-09 13:27:19 +12:00
|
|
|
|
2016-07-09 13:59:10 +12:00
|
|
|
@commands.command(pass_context=True, no_pm=True)
|
2016-08-15 14:10:12 +12:00
|
|
|
@checks.custom_perms(send_messages=True)
|
2016-07-09 13:59:10 +12:00
|
|
|
async def listboops(self, ctx):
|
2016-07-18 03:17:47 +12:00
|
|
|
"""Lists all the users you have booped and the amount of times"""
|
2016-09-29 12:39:34 +13:00
|
|
|
r_filter = {'member_id': ctx.message.author.id}
|
|
|
|
boops = await config.get_content('boops', r_filter)
|
|
|
|
if boops is None:
|
2016-07-12 07:27:53 +12:00
|
|
|
await self.bot.say("You have not booped anyone {} Why the heck not...?".format(ctx.message.author.mention))
|
2016-07-18 03:17:47 +12:00
|
|
|
return
|
2016-09-26 16:58:33 +13:00
|
|
|
|
2016-09-29 12:39:34 +13:00
|
|
|
# Just to make this easier, just pay attention to the boops data, now that we have the right entry
|
|
|
|
boops = boops[0]['boops']
|
|
|
|
|
2016-08-16 15:30:52 +12:00
|
|
|
# Same concept as the mostboops method
|
2016-07-29 04:59:12 +12:00
|
|
|
server_member_ids = [member.id for member in ctx.message.server.members]
|
2016-09-29 12:39:34 +13:00
|
|
|
booped_members = {m_id: amt for m_id, amt in boops.items() if m_id in server_member_ids}
|
2016-08-19 05:49:45 +12:00
|
|
|
sorted_booped_members = sorted(booped_members.items(), key=lambda k: k[1], reverse=True)
|
2016-07-31 12:20:55 +12:00
|
|
|
|
|
|
|
output = "\n".join(
|
2016-08-20 10:19:21 +12:00
|
|
|
"{0.display_name}: {1} times".format(discord.utils.get(ctx.message.server.members, id=m_id), amt) for
|
2016-08-19 05:52:25 +12:00
|
|
|
m_id, amt in sorted_booped_members)
|
2016-08-01 07:11:05 +12:00
|
|
|
await self.bot.say("You have booped:```\n{}```".format(output))
|
2016-07-09 13:59:10 +12:00
|
|
|
|
2016-07-09 13:27:19 +12:00
|
|
|
@commands.command(pass_context=True, no_pm=True)
|
2016-08-15 14:10:12 +12:00
|
|
|
@checks.custom_perms(send_messages=True)
|
2016-07-26 03:58:39 +12:00
|
|
|
async def leaderboard(self, ctx):
|
|
|
|
"""Prints a leaderboard of everyone in the server's battling record"""
|
2016-09-29 12:39:34 +13:00
|
|
|
# Create a list of the ID's of all members in this server, for comparison to the records saved
|
2016-07-26 03:58:39 +12:00
|
|
|
server_member_ids = [member.id for member in ctx.message.server.members]
|
2016-09-29 14:19:45 +13:00
|
|
|
battles = await config.get_content('battle_records')
|
|
|
|
battles = [battle for battle in battles if battle['member_id'] in server_member_ids]
|
2016-09-29 12:39:34 +13:00
|
|
|
|
|
|
|
# Sort the members based on their rating
|
|
|
|
sorted_members = sorted(battles, key=lambda k: k['rating'], reverse=True)
|
2016-07-31 12:20:55 +12:00
|
|
|
|
2016-07-26 03:58:39 +12:00
|
|
|
fmt = ""
|
|
|
|
count = 1
|
2016-07-26 06:43:17 +12:00
|
|
|
for x in sorted_members:
|
2016-09-29 14:00:41 +13:00
|
|
|
member_id = x['member_id']
|
|
|
|
rating = x['rating']
|
|
|
|
member = ctx.message.server.get_member(member_id)
|
|
|
|
fmt += "#{}) {} (Rating: {})\n".format(count, member.display_name, rating)
|
2016-07-26 03:58:39 +12:00
|
|
|
count += 1
|
2016-08-22 07:49:43 +12:00
|
|
|
if count >= 11:
|
2016-08-22 07:49:24 +12:00
|
|
|
break
|
2016-08-01 07:11:05 +12:00
|
|
|
await self.bot.say("Battling leaderboard for this server:```\n{}```".format(fmt))
|
2016-07-31 12:20:55 +12:00
|
|
|
|
2016-09-29 14:00:41 +13:00
|
|
|
@commands.command(pass_context=True, no_pm=True)
|
2016-08-15 14:10:12 +12:00
|
|
|
@checks.custom_perms(send_messages=True)
|
2016-09-29 12:39:34 +13:00
|
|
|
async def stats(self, ctx, member: discord.Member = None):
|
2016-07-26 07:57:47 +12:00
|
|
|
"""Prints the battling stats for you, or the user provided"""
|
|
|
|
member = member or ctx.message.author
|
2016-07-31 12:20:55 +12:00
|
|
|
|
2016-09-29 12:39:34 +13:00
|
|
|
# For this one, we don't want to pass a filter, as we do need all battle records
|
|
|
|
# We need this because we want to make a comparison for overall rank
|
2016-08-31 13:48:30 +12:00
|
|
|
all_members = await config.get_content('battle_records')
|
2016-09-29 12:39:34 +13:00
|
|
|
|
|
|
|
# Make a list comprehension to just check if the user has battled
|
|
|
|
if len([entry for entry in all_members if entry['member_id'] == member.id]) == 0:
|
2016-07-26 07:57:47 +12:00
|
|
|
await self.bot.say("That user has not battled yet!")
|
|
|
|
return
|
2016-07-31 12:20:55 +12:00
|
|
|
|
2016-08-16 15:30:52 +12:00
|
|
|
# Same concept as the leaderboard
|
2016-07-26 07:57:47 +12:00
|
|
|
server_member_ids = [member.id for member in ctx.message.server.members]
|
2016-09-29 14:19:45 +13:00
|
|
|
server_members = [stats for stats in all_members if stats['member_id'] in server_member_ids]
|
|
|
|
sorted_server_members = sorted(server_members, key=lambda x: x['rating'], reverse=True)
|
|
|
|
sorted_all_members = sorted(all_members, key=lambda x: x['rating'], reverse=True)
|
2016-09-26 16:58:33 +13:00
|
|
|
|
2016-08-17 03:22:32 +12:00
|
|
|
# Enumurate the list so that we can go through, find the user's place in the list
|
|
|
|
# and get just that for the rank
|
2016-09-29 14:19:45 +13:00
|
|
|
server_rank = [i for i, x in enumerate(sorted_server_members) if x['member_id'] == member.id][0] + 1
|
|
|
|
total_rank = [i for i, x in enumerate(sorted_all_members) if x['member_id'] == member.id][0] + 1
|
2016-08-16 15:30:52 +12:00
|
|
|
# The rest of this is straight forward, just formatting
|
2016-09-29 14:19:45 +13:00
|
|
|
|
2016-09-29 14:20:46 +13:00
|
|
|
entry = [m for m in server_members if m['member_id'] == member.id][0]
|
2016-09-29 14:19:45 +13:00
|
|
|
rating = entry['rating']
|
|
|
|
record = "{}-{}".format(entry['wins'], entry['losses'])
|
2016-07-26 08:15:19 +12:00
|
|
|
fmt = 'Stats for {}:\n\tRecord: {}\n\tServer Rank: {}/{}\n\tOverall Rank: {}/{}\n\tRating: {}'
|
2016-07-31 12:20:55 +12:00
|
|
|
fmt = fmt.format(member.display_name, record, server_rank, len(server_members), total_rank, len(all_members),
|
|
|
|
rating)
|
2016-08-01 07:11:05 +12:00
|
|
|
await self.bot.say('```\n{}```'.format(fmt))
|
2016-07-09 13:27:19 +12:00
|
|
|
|
2016-07-31 12:20:55 +12:00
|
|
|
|
2016-07-09 13:27:19 +12:00
|
|
|
def setup(bot):
|
|
|
|
bot.add_cog(Stats(bot))
|