diff --git a/bot.py b/bot.py index ce6846f..f1882c0 100644 --- a/bot.py +++ b/bot.py @@ -419,6 +419,39 @@ def save_giveaway_to_db(guild_id, platform, name, prize_uuid, game_key): if connection: close_database_connection(connection) +def create_winner_slots_in_db(guild_id, platform, name, num_winners, game_key="PREDEFINED_GAME_KEY"): + """Erstellt vorab Datenbank-Einträge für alle möglichen Gewinner mit eigenen UUIDs""" + winner_uuids = [] + for i in range(num_winners): + connection = None + cursor = None + try: + connection = connect_to_database() + cursor = connection.cursor() + winner_uuid = uuid.uuid4() + insert_query = """ + INSERT INTO giveaway_data (guild_id, uuid, platform, name, game_key, winner_dc_id) + VALUES (%s, %s, %s, %s, %s, %s) + """ + # winner_dc_id ist zunächst NULL, wird später beim Gewinn gesetzt + data = (guild_id, str(winner_uuid), platform, name, game_key, None) + cursor.execute(insert_query, data) + connection.commit() + winner_uuids.append(winner_uuid) + logger.info(f"Created winner slot {i+1}/{num_winners} with UUID: {winner_uuid}") + except Exception as e: + logger.error(f"Error creating winner slot {i+1}: {e}") + if connection: + connection.rollback() + raise e + finally: + if cursor: + cursor.close() + if connection: + close_database_connection(connection) + + return winner_uuids + def save_winner_to_db(guild_id, platform, name, winner_dc_id, game_key="PREDEFINED_GAME_KEY"): """Erstellt einen eigenen Datenbankeintrag für jeden Gewinner mit eigener UUID""" connection = None @@ -447,6 +480,32 @@ def save_winner_to_db(guild_id, platform, name, winner_dc_id, game_key="PREDEFIN if connection: close_database_connection(connection) +def assign_winner_to_uuid(winner_uuid, winner_dc_id): + """Verknüpft eine bereits existierende UUID mit einem tatsächlichen Gewinner""" + connection = None + cursor = None + try: + connection = connect_to_database() + cursor = connection.cursor() + update_query = """ + UPDATE giveaway_data SET winner_dc_id = %s WHERE uuid = %s + """ + data = (winner_dc_id, str(winner_uuid)) + cursor.execute(update_query, data) + connection.commit() + logger.info(f"Successfully assigned winner {winner_dc_id} to UUID: {winner_uuid}") + return True + except Exception as e: + logger.error(f"Error assigning winner to UUID: {e}") + if connection: + connection.rollback() + raise e + finally: + if cursor: + cursor.close() + if connection: + close_database_connection(connection) + def update_winner_in_db(guild_id, prize_uuid, winner_dc_id): connection = None cursor = None @@ -483,11 +542,12 @@ class Giveaway: self.duration = duration self.end_time = end_time self.participants = [] - self.prize_uuid = uuid.uuid4() # Generiert eine eindeutige UUID + self.prize_uuid = uuid.uuid4() # Generiert eine eindeutige UUID für das Gewinnspiel self.game_key = f"PREDEFINED_GAME_KEY" # Platzhalter für den tatsächlichen Game-Key - # Speichern des Giveaways in der Datenbank - save_giveaway_to_db(self.guild_id, self.platform, self.title, self.prize_uuid, self.game_key) + # Erstelle nur die Gewinner-Einträge, KEINEN Haupt-Eintrag + self.winner_uuids = create_winner_slots_in_db(self.guild_id, self.platform, self.title, self.num_winners, self.game_key) + logger.info(f"Created giveaway '{self.title}' with {len(self.winner_uuids)} winner slots: {[str(uuid) for uuid in self.winner_uuids]}") def add_participant(self, user): if user not in self.participants: @@ -697,17 +757,21 @@ async def check_giveaway(giveaway_id): winner_mentions = ", ".join([winner.mention for winner in winners]) await giveaway.ctx.send(f"🎉 Congratulations to the winners of the giveaway '{giveaway.title}'! The winners are: {winner_mentions}") - # Notify and update the winners - Erstelle für jeden Gewinner einen eigenen DB-Eintrag + # Verwende die bereits erstellten UUIDs und weise sie den tatsächlichen Gewinnern zu logger.info(f"Processing {len(winners)} winners for giveaway '{giveaway.title}'") for i, winner in enumerate(winners): try: user_data = load_user_data(winner.id, giveaway.guild_id) - # Erstelle einen eigenen Datenbankeintrag für diesen Gewinner mit eigener UUID - logger.info(f"Creating database entry for winner {i+1}/{len(winners)}: {winner.name} (ID: {winner.id})") - winner_uuid = save_winner_to_db(giveaway.guild_id, giveaway.platform, giveaway.title, winner.id) - logger.info(f"Created winner entry with UUID: {winner_uuid}") + # Verwende die bereits beim Erstellen generierte UUID + winner_uuid = giveaway.winner_uuids[i] # i-te UUID für i-ten Gewinner + logger.info(f"Assigning winner {i+1}/{len(winners)}: {winner.name} (ID: {winner.id}) to existing UUID: {winner_uuid}") + + # Verknüpfe die bereits vorhandene UUID mit dem tatsächlichen Gewinner + assign_winner_to_uuid(winner_uuid, winner.id) + await winner.send(f"🎁 Congratulations! You won the giveaway '{giveaway.title}'!\n" f"Please claim your prize using the following link: {GIVEAWAY_WEBSITE_URL}{giveaway.guild_id}/{winner_uuid}") + logger.info(f"Sent winner notification with UUID: {winner_uuid}") except Exception as e: logger.error(f"Error processing winner {winner.name}: {e}") else: @@ -718,7 +782,7 @@ async def check_giveaway(giveaway_id): @client.event async def on_interaction(interaction): """Processes participation in a giveaway.""" - # Überprüfen, ob es sich um eine Button-Interaktion handelt und ein custom_id vorhanden ist + # Nur Button-Interaktionen für Giveaways verarbeiten if interaction.type == discord.InteractionType.component and "custom_id" in interaction.data: if interaction.data["custom_id"].startswith("giveaway_"): giveaway_id = int(interaction.data["custom_id"].split("_")[1]) @@ -733,9 +797,7 @@ async def on_interaction(interaction): await interaction.response.send_message("You have successfully entered the giveaway!", ephemeral=True) else: await interaction.response.send_message("You're already participating in this giveaway.", ephemeral=True) - else: - # Logge Interaktionen, die nicht den erwarteten Typ haben - logger.error(f"Unbekannte Interaktion: {interaction.type}, Daten: {interaction.data}") + # Slash Commands und andere Interaktionen werden automatisch vom Framework verarbeitet def read_introduction(): try: