diff --git a/cogs/leaderboards.py b/cogs/leaderboards.py new file mode 100644 index 0000000..7cbe0b1 --- /dev/null +++ b/cogs/leaderboards.py @@ -0,0 +1,85 @@ +import discord +from discord.ext import commands +from data.DatabaseConnection import * +from datetime import datetime, timedelta + +class Leaderboards(commands.Cog): + def __init__(self, client): + self.client = client + + @commands.group(name="top",case_insensitive=True, invoke_without_command=True) + async def top(self, ctx, *args): + pass + + def create_leaderboard_embed(self, title, column, time=False): + + def seconds_to_time(s): + t = timedelta(seconds=s) + d = datetime(1,1,1) + t + res = "" + if d.day - 1 > 0: + res += f"{d.day - 1}d " + if d.day - 1 > 0 or d.hour > 0: + res += f"{d.hour}h ".zfill(4) + if d.day - 1 > 0 or d.hour > 0 or d.minute > 0: + res += f"{d.minute}m ".zfill(4) + if d.day - 1 > 0 or d.hour > 0 or d.minute > 0 or d.second > 0: + res += f"{d.second}s".zfill(3) + return res + + playerdb = PlayerDBLinker() + top_players = playerdb.get_stats(column) + playerdb.close() + embed = discord.Embed() + embed.colour = discord.Colour.orange() + embed.set_author(name="Top") + message = "" + space = 6 + longestname = 13 + longestscore = 0 + for player in top_players: + longestname = max(longestname, len(player["playerName"])) + longestscore = max(longestscore, len(str(player["stat"]))) + + message += f"Pos {' ' * (space - 3)}Minecraftname{' ' * (longestname - 13)} {title}\n\n" + for i, player in enumerate(top_players): + message += f"{str(i + 1)}){' ' * (space - len(str(i + 1)))}{player['playerName']}{' ' * (longestname - len(player['playerName']))} {seconds_to_time(player['stat']) if time else player['stat']}\n" + + embed.add_field(name=f"{title}:", value=f"```{message}```", inline=False) + return embed + + @top.command(name="broken", case_insensitive=True) + async def top_broken(self, ctx): + await ctx.send(embed=self.create_leaderboard_embed("Broken blocks", "brokenBlocks")) + + @top.command(name="kills", case_insensitive=True) + async def top_kills(self, ctx): + await ctx.send(embed=self.create_leaderboard_embed("Kills", "pvpKills")) + + @top.command(name="deaths", case_insensitive=True) + async def top_deaths(self, ctx): + await ctx.send(embed=self.create_leaderboard_embed("Deaths", "pvpDeaths")) + + @top.command(name="level", case_insensitive=True) + async def top_level(self, ctx): + await ctx.send(embed=self.create_leaderboard_embed("Deaths", "playerLevel")) + + @top.command(name="placed", case_insensitive=True) + async def top_placed(self, ctx): + await ctx.send(embed=self.create_leaderboard_embed("Placed blocks", "placedBlocks")) + + @top.command(name="playedtime", aliases=["onlinetime"], case_insensitive=True) + async def top_playedtime(self, ctx): + await ctx.send(embed=self.create_leaderboard_embed("Played time", "onlineTime", time=True)) + + @top.command(name="sailed", case_insensitive=True) + async def top_sailed(self, ctx): + await ctx.send(embed=self.create_leaderboard_embed("Sailed", "waterTravelledBlocks")) + + @top.command(name="walked", case_insensitive=True) + async def top_walked(self, ctx): + await ctx.send(embed=self.create_leaderboard_embed("Walked", "travelledBlocks")) + + +def setup(client): + client.add_cog(Leaderboards(client)) diff --git a/data/DatabaseConnection.py b/data/DatabaseConnection.py index e21b107..8d1c688 100755 --- a/data/DatabaseConnection.py +++ b/data/DatabaseConnection.py @@ -43,8 +43,8 @@ class DatabaseConnection: def get_db(self): return self.mydb - def get_cursor(self): - return self.cursor + def get_cursor(self, dictionary=False): + return self.mydb.cursor(dictionary=dictionary) def close(self): self.mydb.close() @@ -202,6 +202,21 @@ class PlayerDBLinker: else: raise PlayerNotLinked() + #Broken + #Deaths + #kills + #level + #placed + #playedtime/onlinetime + #sailed + #walked + def get_stats(self, categorie, limit = 20): + serverdb_cursor = self.serverdbconn.get_cursor(dictionary=True) + sql = f"SELECT playerName, {categorie} as stat FROM playerprofiles ORDER BY {categorie} DESC LIMIT {str(limit)}" + serverdb_cursor.execute(sql) + return list(serverdb_cursor.fetchall()) + + def close(self): self.discorddbconn.close() self.serverdbconn.close()