diff --git a/cogs/mystats.py b/cogs/mystats.py index 96b9f84..d9edc43 100644 --- a/cogs/mystats.py +++ b/cogs/mystats.py @@ -3,7 +3,7 @@ import discord from discord.ext import commands from config import AUTHORIZED_CHANNEL_ID, BOSS_CONFIG from utils.helpers import format_damage_display, format_date_only -from utils.pb_handler import db_manager # Assurez-vous que db_manager est initialisé correctement +from utils.pb_handler import db_manager # Assurez-vous que db_manager est initialisé correctement class MyStats(commands.Cog): """Cog pour afficher tous les PB d'un utilisateur""" @@ -13,24 +13,24 @@ class MyStats(commands.Cog): @commands.command(name="mystats") async def mystats(self, ctx, target_user: str = None): - """Affiche tous les PB d'un utilisateur avec les nouvelles difficultés""" + """Affiche tous les PB d'un utilisateur avec les nouvelles difficultés""" if ctx.channel.id != AUTHORIZED_CHANNEL_ID: return try: - username = target_user if target_user else ctx.author.display_name + username = target_user if target_user else ctx.author.id user_data = db_manager.get_user_all_pbs(username) if not user_data: - await ctx.send(f"❌ No data found for **{username}**.") + await ctx.send(f"❌ No data found for **{username}**.") return embed = discord.Embed( - title=f"📊 {username}'s Complete Stats", + title=f"📊 {ctx.author.display_name}'s Complete Stats", color=0x00bfff ) - # Hydra - toutes les difficultés + # Hydra - toutes les difficultés hydra_stats = [] for difficulty in BOSS_CONFIG['hydra']['difficulties']: pb_key = f'pb_hydra_{difficulty}' @@ -39,13 +39,13 @@ class MyStats(commands.Cog): if pb_key in user_data and user_data[pb_key] > 0: pb_value = user_data[pb_key] pb_date = user_data.get(date_key) - date_text = f" • {format_date_only(pb_date)}" if pb_date else "" + date_text = f" • {format_date_only(pb_date)}" if pb_date else "" hydra_stats.append(f"**{difficulty.title()}:** {format_damage_display(pb_value)}{date_text}") hydra_text = "\n".join(hydra_stats) if hydra_stats else "No records" - embed.add_field(name="🗡️ Hydra PBs", value=hydra_text, inline=False) + embed.add_field(name="🗡️ Hydra PBs", value=hydra_text, inline=False) - # Chimera - toutes les difficultés + # Chimera - toutes les difficultés chimera_stats = [] for difficulty in BOSS_CONFIG['chimera']['difficulties']: pb_key = f'pb_chimera_{difficulty}' @@ -54,12 +54,12 @@ class MyStats(commands.Cog): if pb_key in user_data and user_data[pb_key] > 0: pb_value = user_data[pb_key] pb_date = user_data.get(date_key) - date_text = f" • {format_date_only(pb_date)}" if pb_date else "" + date_text = f" • {format_date_only(pb_date)}" if pb_date else "" display_name = "Ultra Nightmare" if difficulty == "ultra" else difficulty.title() chimera_stats.append(f"**{display_name}:** {format_damage_display(pb_value)}{date_text}") chimera_text = "\n".join(chimera_stats) if chimera_stats else "No records" - embed.add_field(name="🛡️ Chimera PBs", value=chimera_text, inline=False) + embed.add_field(name="🛡️ Chimera PBs", value=chimera_text, inline=False) # CvC cvc_pb = user_data.get('pb_cvc', 0) @@ -68,19 +68,19 @@ class MyStats(commands.Cog): if cvc_pb > 0 and cvc_date: formatted_date = format_date_only(cvc_date) if formatted_date: - cvc_text += f" • {formatted_date}" - embed.add_field(name="⚔️ CvC PB", value=cvc_text, inline=False) + cvc_text += f" • {formatted_date}" + embed.add_field(name="⚔️ CvC PB", value=cvc_text, inline=False) - # Total combiné + # Total combiné total_damage = sum(user_data.get(f'pb_hydra_{d}', 0) for d in BOSS_CONFIG['hydra']['difficulties']) total_damage += sum(user_data.get(f'pb_chimera_{d}', 0) for d in BOSS_CONFIG['chimera']['difficulties']) total_damage += user_data.get('pb_cvc', 0) - embed.add_field(name="💯 Total Combined Damage", value=f"**{format_damage_display(total_damage)}**", inline=False) + embed.add_field(name="💯 Total Combined Damage", value=f"**{format_damage_display(total_damage)}**", inline=False) await ctx.send(embed=embed) except Exception as e: - await ctx.send(f"❌ Error: {e}") + await ctx.send(f"❌ Error: {e}") async def setup(bot): await bot.add_cog(MyStats(bot)) diff --git a/utils/DatabaseManager_class.py b/utils/DatabaseManager_class.py index d1eac49..31271c3 100644 --- a/utils/DatabaseManager_class.py +++ b/utils/DatabaseManager_class.py @@ -17,7 +17,8 @@ class DatabaseManager: cursor.execute(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, - discord_username TEXT UNIQUE, + discord_id TEXT UNIQUE, + discord_username TEXT, -- Hydra difficulties pb_hydra_normal INTEGER DEFAULT 0, @@ -63,10 +64,19 @@ class DatabaseManager: ) ''') + # Migration des données existantes (si nécessaire) + cursor.execute("PRAGMA table_info(users)") + columns = [row[1] for row in cursor.fetchall()] + + if 'discord_id' not in columns: + cursor.execute('ALTER TABLE users ADD COLUMN discord_id TEXT') + # Note: Vous devrez peut-être faire une migration manuelle pour les données existantes + # Table pour l'historique global cursor.execute(''' CREATE TABLE IF NOT EXISTS pb_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, + discord_id TEXT, username TEXT, boss_type TEXT, difficulty TEXT, @@ -79,7 +89,7 @@ class DatabaseManager: conn.commit() conn.close() - def get_user_pb(self, username, boss_type, difficulty=None): + def get_user_pb(self, user_id, boss_type, difficulty=None): """Récupère le PB d'un utilisateur pour un boss et difficulté spécifique""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() @@ -90,21 +100,21 @@ class DatabaseManager: column_prefix = f"pb_{boss_type}" cursor.execute( - f"SELECT {column_prefix}, {column_prefix}_screenshot, {column_prefix}_date FROM users WHERE discord_username = ?", - (username.lower(),) + f"SELECT {column_prefix}, {column_prefix}_screenshot, {column_prefix}_date FROM users WHERE discord_id = ?", + (str(user_id),) ) result = cursor.fetchone() conn.close() return result if result else (0, None, None) - def update_user_pb(self, username, boss_type, damage, screenshot_filename, difficulty=None): + def update_user_pb(self, user_id, username, boss_type, damage, screenshot_filename, difficulty=None): """Met à jour le PB d'un utilisateur et supprime l'ancien screenshot""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() # Récupérer l'ancien screenshot pour le supprimer - old_data = self.get_user_pb(username, boss_type, difficulty) + old_data = self.get_user_pb(user_id, boss_type, difficulty) old_screenshot = old_data[1] if old_data else None if difficulty: @@ -114,21 +124,22 @@ class DatabaseManager: # Créer l'utilisateur s'il n'existe pas, sinon mettre à jour cursor.execute(f''' - INSERT INTO users (discord_username, {column_prefix}, {column_prefix}_screenshot, {column_prefix}_date, total_attempts) - VALUES (?, ?, ?, CURRENT_TIMESTAMP, 1) - ON CONFLICT(discord_username) + INSERT INTO users (discord_id, discord_username, {column_prefix}, {column_prefix}_screenshot, {column_prefix}_date, total_attempts) + VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, 1) + ON CONFLICT(discord_id) DO UPDATE SET + discord_username = ?, {column_prefix} = ?, {column_prefix}_screenshot = ?, {column_prefix}_date = CURRENT_TIMESTAMP, total_attempts = total_attempts + 1 - ''', (username.lower(), damage, screenshot_filename, damage, screenshot_filename)) + ''', (str(user_id), username, damage, screenshot_filename, username, damage, screenshot_filename)) # Ajouter à l'historique cursor.execute(''' - INSERT INTO pb_history (username, boss_type, difficulty, damage, screenshot_filename) - VALUES (?, ?, ?, ?, ?) - ''', (username.lower(), boss_type, difficulty or 'none', damage, screenshot_filename)) + INSERT INTO pb_history (discord_id, username, boss_type, difficulty, damage, screenshot_filename) + VALUES (?, ?, ?, ?, ?, ?) + ''', (str(user_id), username, boss_type, difficulty or 'none', damage, screenshot_filename)) conn.commit() conn.close() @@ -164,13 +175,13 @@ class DatabaseManager: conn.close() return results - def get_user_all_pbs(self, username): + def get_user_all_pbs(self, user_id): """Récupère tous les PB d'un utilisateur""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() # Récupérer toutes les colonnes de PB - cursor.execute('SELECT * FROM users WHERE discord_username = ?', (username.lower(),)) + cursor.execute('SELECT * FROM users WHERE discord_id = ?', (str(user_id),)) result = cursor.fetchone() columns = [desc[0] for desc in cursor.description] conn.close() @@ -179,3 +190,14 @@ class DatabaseManager: return None return dict(zip(columns, result)) + + def find_user_by_name(self, username): + """Trouve un utilisateur par son nom (pour rétrocompatibilité)""" + conn = sqlite3.connect(self.db_path) + cursor = conn.cursor() + + cursor.execute('SELECT discord_id, discord_username FROM users WHERE discord_username LIKE ?', (f'%{username}%',)) + results = cursor.fetchall() + conn.close() + + return results \ No newline at end of file diff --git a/utils/helpers.py b/utils/helpers.py index d5eb931..6cd9787 100644 --- a/utils/helpers.py +++ b/utils/helpers.py @@ -45,6 +45,8 @@ def normalize_difficulty(difficulty): def get_user_clan(username): """Détermine le clan d'un utilisateur basé sur son pseudo""" + if not username: + return None username_upper = username.upper() # Tags avec crochets et espace for clan_tag in ['[RTF] ', '[RTFC] ', '[RTFR] ']: @@ -56,6 +58,10 @@ def get_user_clan(username): return clan_tag.replace('[', '').replace(']', '') return None +def get_user_clan_from_ctx(ctx): + """Détermine le clan d'un utilisateur depuis le contexte Discord""" + return get_user_clan(ctx.author.display_name) + def format_datetime(date_str): """Formate une date en format AM/PM""" if not date_str: @@ -108,4 +114,4 @@ def calc_chance_and_guarantee(shard_type, pulls): chance = rule["base"] if pulls < rule["start"] else rule["base"] + (pulls - rule["start"]) * rule["increment"] guaranteed_at = int(rule["start"] + (100 - rule["base"]) / rule["increment"]) remaining = max(0, guaranteed_at - pulls) - return chance, guaranteed_at, remaining + return chance, guaranteed_at, remaining \ No newline at end of file diff --git a/utils/pb_handler.py b/utils/pb_handler.py index b2ae68c..50999eb 100644 --- a/utils/pb_handler.py +++ b/utils/pb_handler.py @@ -90,8 +90,9 @@ async def handle_pb_submission(ctx, boss_type, difficulty, damage): await ctx.send("⚠️ Please attach a valid image file!") return + user_id = ctx.author.id username = ctx.author.display_name - current_pb, _, _ = db_manager.get_user_pb(username, boss_type, difficulty) + current_pb, _, _ = db_manager.get_user_pb(user_id, boss_type, difficulty) if damage > current_pb: screenshot_filename = await screenshot_manager.save_screenshot( @@ -100,7 +101,7 @@ async def handle_pb_submission(ctx, boss_type, difficulty, damage): if screenshot_filename: old_screenshot = db_manager.update_user_pb( - username, boss_type, damage, screenshot_filename, difficulty + user_id, username, boss_type, damage, screenshot_filename, difficulty ) if old_screenshot: @@ -133,13 +134,35 @@ async def handle_pb_submission(ctx, boss_type, difficulty, damage): async def show_user_pb(ctx, boss_type, difficulty, target_user): """Affiche le PB actuel d'un utilisateur""" - current_pb, screenshot, date = db_manager.get_user_pb(target_user, boss_type, difficulty) + # Si target_user est un nom d'utilisateur, on essaie de le trouver + if isinstance(target_user, str) and not target_user.isdigit(): + # D'abord, vérifier si c'est l'utilisateur actuel + if target_user.lower() == ctx.author.display_name.lower(): + user_id = ctx.author.id + display_name = ctx.author.display_name + else: + # Chercher dans la base de données + matches = db_manager.find_user_by_name(target_user) + if not matches: + await ctx.send(f"⚠️ User **{target_user}** not found in database.") + return + elif len(matches) > 1: + await ctx.send(f"⚠️ Multiple users found for **{target_user}**. Please be more specific.") + return + else: + user_id, display_name = matches[0] + else: + # Si c'est l'utilisateur actuel + user_id = ctx.author.id + display_name = ctx.author.display_name + + current_pb, screenshot, date = db_manager.get_user_pb(user_id, boss_type, difficulty) boss_info = BOSS_CONFIG[boss_type] difficulty_name = get_difficulty_display_name(difficulty) if difficulty else "" if current_pb > 0: embed = discord.Embed( - title=f"📊 {target_user}'s {difficulty_name} {boss_info['name']} PB", + title=f"📊 {display_name}'s {difficulty_name} {boss_info['name']} PB", description=f"**{format_damage_display(current_pb)} damage**", color=0x00bfff ) @@ -157,4 +180,4 @@ async def show_user_pb(ctx, boss_type, difficulty, target_user): await ctx.send(embed=embed) else: - await ctx.send(f"⚠️ No PB found for **{target_user}** on {difficulty_name} {boss_info['name']}.") + await ctx.send(f"⚠️ No PB found for **{display_name}** on {difficulty_name} {boss_info['name']}.") \ No newline at end of file