Made period optional added player cache should fix user user_id on lb instead of usernames
150 lines
4.5 KiB
Python
Executable File
150 lines
4.5 KiB
Python
Executable File
import discord
|
|
from discord.ext import commands
|
|
from discord import app_commands
|
|
import sqlite3
|
|
|
|
class Leaderboard(commands.Cog):
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
|
|
@app_commands.choices(
|
|
leaderboard_type=[
|
|
app_commands.Choice(name="Accuracy", value="accuracy"),
|
|
app_commands.Choice(name="Perfect Games", value="perfect")
|
|
],
|
|
period=[
|
|
app_commands.Choice(name="Monthly", value="monthly"),
|
|
app_commands.Choice(name="Yearly", value="yearly"),
|
|
app_commands.Choice(name="All Time", value="alltime")
|
|
]
|
|
)
|
|
@app_commands.command(
|
|
name="leaderboard",
|
|
description="Show a leaderboard"
|
|
)
|
|
async def leaderboard(
|
|
self,
|
|
interaction: discord.Interaction,
|
|
leaderboard_type: str,
|
|
period: str = "alltime"
|
|
):
|
|
try:
|
|
if leaderboard_type == "accuracy":
|
|
msg = Leaderboard.get_accuracy_leaderboard(
|
|
self,
|
|
period,
|
|
interaction.guild
|
|
)
|
|
|
|
elif leaderboard_type == "perfect":
|
|
msg = Leaderboard.get_perfect_score_leaderboard(
|
|
self,
|
|
period,
|
|
interaction.guild
|
|
)
|
|
|
|
await interaction.response.send_message(msg)
|
|
|
|
except Exception as e:
|
|
print("Leaderboard error:", e)
|
|
await interaction.response.send_message(
|
|
"Error loading leaderboard."
|
|
)
|
|
|
|
def get_playername(self, user_id : int):
|
|
member = self.bot.player_cache.get(user_id)
|
|
|
|
if member:
|
|
name = member.display_name
|
|
else:
|
|
name = f"User {user_id}"
|
|
|
|
return name
|
|
|
|
def get_accuracy_leaderboard(self, period, guild):
|
|
conn = sqlite3.connect("Goonerdle.db")
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute("""
|
|
SELECT
|
|
User_ID,
|
|
COUNT(*) AS games_played,
|
|
ROUND(
|
|
(SUM(Result) * 100.0) /
|
|
(COUNT(*) * 10),
|
|
2
|
|
) AS accuracy
|
|
FROM Result
|
|
WHERE
|
|
? = 'alltime'
|
|
OR (
|
|
? = 'monthly'
|
|
AND DateScore >= date('now', 'start of month')
|
|
)
|
|
OR (
|
|
? = 'yearly'
|
|
AND DateScore >= date('now', 'start of year')
|
|
)
|
|
GROUP BY User_ID
|
|
HAVING COUNT(*) >= 5
|
|
ORDER BY accuracy DESC
|
|
LIMIT 10
|
|
""", (period, period, period))
|
|
|
|
rows = cursor.fetchall()
|
|
conn.close()
|
|
|
|
lines = []
|
|
|
|
for position, (user_id, games_played, accuracy) in enumerate(rows, start=1):
|
|
name = Leaderboard.get_playername(self, user_id)
|
|
|
|
lines.append(
|
|
f"{position}. {name} — **{accuracy:.2f}%** ({games_played} games)"
|
|
)
|
|
|
|
return f"🏆 **Accuracy Leaderboard {period}** 🏆\n\n" + "\n".join(lines)
|
|
|
|
def get_perfect_score_leaderboard(self, period, guild):
|
|
conn = sqlite3.connect("Goonerdle.db")
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute("""
|
|
SELECT
|
|
User_ID,
|
|
COUNT(*) AS perfect_games
|
|
FROM Result
|
|
WHERE
|
|
Result = 10
|
|
AND (
|
|
? = 'alltime'
|
|
OR (
|
|
? = 'monthly'
|
|
AND DateScore >= date('now', 'start of month')
|
|
)
|
|
OR (
|
|
? = 'yearly'
|
|
AND DateScore >= date('now', 'start of year')
|
|
)
|
|
)
|
|
GROUP BY User_ID
|
|
ORDER BY perfect_games DESC
|
|
LIMIT 10
|
|
""", (period, period, period))
|
|
|
|
rows = cursor.fetchall()
|
|
conn.close()
|
|
|
|
lines = []
|
|
|
|
for position, (user_id, perfect_games) in enumerate(rows, start=1):
|
|
name = Leaderboard.get_playername(self, user_id)
|
|
|
|
lines.append(
|
|
f"{position}. {name} — **{perfect_games}** perfect games"
|
|
)
|
|
|
|
return f"🏆 **Perfect Game Leaderboard {period}** 🏆\n\n" + "\n".join(lines)
|
|
|
|
async def setup(bot):
|
|
await bot.add_cog(Leaderboard(bot)) |