From 04dd33dc03188bc1f46138b357e2ee3b9681500a Mon Sep 17 00:00:00 2001 From: SimolZimol <70102430+SimolZimol@users.noreply.github.com> Date: Thu, 9 Oct 2025 01:27:28 +0200 Subject: [PATCH] modified: bot.py --- bot.py | 311 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 292 insertions(+), 19 deletions(-) diff --git a/bot.py b/bot.py index 48fd381..0280d03 100644 --- a/bot.py +++ b/bot.py @@ -14,6 +14,8 @@ import base64 import mysql.connector import mysql.connector.pooling import json +import re +import aiohttp import logging import time import random @@ -836,22 +838,123 @@ async def handle_expired_giveaway(process_uuid, data): # Execute giveaway ending logic winners = giveaway.pick_winners() if winners: - 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}") + # Create enhanced winner announcement + winner_embed = discord.Embed( + title="๐ŸŽ‰ Giveaway Winners Announced!", + description=f"**{giveaway.title}** has ended!", + color=0xFFD700, + timestamp=datetime.now() + ) + + # Enhanced prize display with game info + if hasattr(giveaway, 'game_info') and giveaway.game_info and giveaway.game_info.get('name'): + if hasattr(giveaway, 'game_url') and giveaway.game_url: + prize_text = f"**[{giveaway.game_info['name']}]({giveaway.game_url})**" + else: + prize_text = f"**{giveaway.game_info['name']}**" + else: + if hasattr(giveaway, 'game_url') and giveaway.game_url: + prize_text = f"**[{giveaway.prize}]({giveaway.game_url})**" + else: + prize_text = f"**{giveaway.prize}**" + + winner_embed.add_field(name="๐ŸŽ Prize", value=prize_text, inline=True) + winner_embed.add_field(name="๐ŸŽฎ Platform", value=f"**{giveaway.platform}**", inline=True) + winner_embed.add_field(name="๐Ÿ‘ฅ Total Participants", value=f"**{len(giveaway.participants)}**", inline=True) + + # List winners + winner_list = [] + for i, winner in enumerate(winners, 1): + winner_list.append(f"๏ฟฝ **#{i}** {winner.mention}") + + winner_embed.add_field(name="๐ŸŽŠ Winners", value="\n".join(winner_list), inline=False) + + # Add sponsor info if available + if hasattr(giveaway, 'sponsor') and giveaway.sponsor: + winner_embed.add_field(name="๐Ÿ’ Sponsored by", value=f"**{giveaway.sponsor}**", inline=False) + + winner_embed.add_field(name="๐Ÿ“ง Next Steps", + value="Winners have been sent a DM with prize claim instructions!", + inline=False) + + # Set game image if available + if hasattr(giveaway, 'game_info') and giveaway.game_info and giveaway.game_info.get('image_url'): + winner_embed.set_image(url=giveaway.game_info['image_url']) + winner_embed.set_thumbnail(url="https://cdn.discordapp.com/emojis/1028701098145587302.png") + else: + winner_embed.set_thumbnail(url="https://cdn.discordapp.com/emojis/1028701098145587302.png") + + winner_embed.set_footer(text="Congratulations to all winners! ๐ŸŽ‰") + + await giveaway.ctx.send(embed=winner_embed) - # Process winners + # Process winners with enhanced DM for i, winner in enumerate(winners): try: if i < len(giveaway.winner_uuids): winner_uuid = giveaway.winner_uuids[i] 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}") + # Enhanced winner DM + dm_embed = discord.Embed( + title="๏ฟฝ Congratulations! You Won!", + description=f"You are a winner in the **{giveaway.title}** giveaway!", + color=0xFFD700, + timestamp=datetime.now() + ) + + # Enhanced prize display in DM + if hasattr(giveaway, 'game_info') and giveaway.game_info and giveaway.game_info.get('name'): + if hasattr(giveaway, 'game_url') and giveaway.game_url: + prize_text = f"**[{giveaway.game_info['name']}]({giveaway.game_url})**" + else: + prize_text = f"**{giveaway.game_info['name']}**" + else: + if hasattr(giveaway, 'game_url') and giveaway.game_url: + prize_text = f"**[{giveaway.prize}]({giveaway.game_url})**" + else: + prize_text = f"**{giveaway.prize}**" + + dm_embed.add_field(name="๐ŸŽ Your Prize", value=prize_text, inline=True) + dm_embed.add_field(name="๐ŸŽฎ Platform", value=f"**{giveaway.platform}**", inline=True) + dm_embed.add_field(name="๐Ÿ† Position", value=f"**#{i+1}**", inline=True) + + if hasattr(giveaway, 'sponsor') and giveaway.sponsor: + dm_embed.add_field(name="๐Ÿ’ Sponsored by", value=f"**{giveaway.sponsor}**", inline=False) + + dm_embed.add_field(name="๐Ÿ”— Claim Your Prize", + value=f"[Click here to claim your prize]({GIVEAWAY_WEBSITE_URL}{giveaway.guild_id}/{winner_uuid})", + inline=False) + + dm_embed.set_footer(text=f"Server: {giveaway.ctx.guild.name}") + + # Set game image in DM if available + if hasattr(giveaway, 'game_info') and giveaway.game_info and giveaway.game_info.get('image_url'): + dm_embed.set_thumbnail(url=giveaway.game_info['image_url']) + else: + dm_embed.set_thumbnail(url="https://cdn.discordapp.com/emojis/1028701098145587302.png") + + await winner.send(embed=dm_embed) except Exception as e: logger.error(f"Error processing winner {winner.name}: {e}") else: - await giveaway.ctx.send(f"The giveaway '{giveaway.title}' has ended, but there were no participants.") + # Enhanced "no participants" message + no_participants_embed = discord.Embed( + title="๐Ÿ˜” Giveaway Ended", + description=f"**{giveaway.title}** has ended with no participants.", + color=0xFF6B6B, + timestamp=datetime.now() + ) + + no_participants_embed.add_field(name="๐ŸŽ Prize", value=f"**{giveaway.prize}**", inline=True) + no_participants_embed.add_field(name="๐ŸŽฎ Platform", value=f"**{giveaway.platform}**", inline=True) + + if hasattr(giveaway, 'sponsor') and giveaway.sponsor: + no_participants_embed.add_field(name="๐Ÿ’ Sponsored by", value=f"**{giveaway.sponsor}**", inline=False) + + no_participants_embed.set_footer(text="Better luck next time!") + + await giveaway.ctx.send(embed=no_participants_embed) # Clean up if giveaway_id in giveaways: @@ -1239,6 +1342,82 @@ def save_winner_to_db(guild_id, platform, name, winner_dc_id, game_key="PREDEFIN if connection: close_database_connection(connection) +async def extract_game_info(game_url: str): + """Extract game information from various game store URLs""" + try: + # Steam URL pattern + steam_pattern = r'https?://store\.steampowered\.com/app/(\d+)' + steam_match = re.search(steam_pattern, game_url) + + if steam_match: + app_id = steam_match.group(1) + return await get_steam_game_info(app_id) + + # Epic Games Store URL pattern + epic_pattern = r'https?://store\.epicgames\.com/[^/]+/p/([^/?]+)' + epic_match = re.search(epic_pattern, game_url) + + if epic_match: + game_slug = epic_match.group(1) + return { + 'name': game_slug.replace('-', ' ').title(), + 'image_url': None, + 'store_url': game_url, + 'platform': 'Epic Games' + } + + # Generic fallback + return { + 'name': None, + 'image_url': None, + 'store_url': game_url, + 'platform': 'Unknown' + } + + except Exception as e: + logger.error(f"Error extracting game info from URL {game_url}: {e}") + return None + +async def get_steam_game_info(app_id: str): + """Get game information from Steam API""" + try: + async with aiohttp.ClientSession() as session: + # Steam Store API + steam_api_url = f"https://store.steampowered.com/api/appdetails?appids={app_id}" + + async with session.get(steam_api_url) as response: + if response.status == 200: + data = await response.json() + + if app_id in data and data[app_id]['success']: + game_data = data[app_id]['data'] + + return { + 'name': game_data.get('name', 'Unknown Game'), + 'image_url': game_data.get('header_image'), + 'store_url': f"https://store.steampowered.com/app/{app_id}", + 'platform': 'Steam', + 'description': game_data.get('short_description', ''), + 'price': game_data.get('price_overview', {}).get('final_formatted', 'Free') + } + + # Fallback if API fails + return { + 'name': None, + 'image_url': f"https://cdn.akamai.steamstatic.com/steam/apps/{app_id}/header.jpg", + 'store_url': f"https://store.steampowered.com/app/{app_id}", + 'platform': 'Steam' + } + + except Exception as e: + logger.error(f"Error fetching Steam game info for app {app_id}: {e}") + return { + 'name': None, + 'image_url': f"https://cdn.akamai.steamstatic.com/steam/apps/{app_id}/header.jpg", + 'store_url': f"https://store.steampowered.com/app/{app_id}", + 'platform': 'Steam' + } + def assign_winner_to_uuid(winner_uuid, winner_dc_id): """Verknรผpft eine bereits existierende UUID mit einem tatsรคchlichen Gewinner""" connection = None @@ -1290,7 +1469,7 @@ def update_winner_in_db(guild_id, prize_uuid, winner_dc_id): close_database_connection(connection) class Giveaway: - def __init__(self, ctx, platform, prize, num_winners, title, subtitle, duration, end_time): + def __init__(self, ctx, platform, prize, num_winners, title, subtitle, duration, end_time, sponsor=None, game_url=None, game_info=None): self.ctx = ctx self.guild_id = ctx.guild.id # Speichern der guild_id self.platform = platform @@ -1300,6 +1479,9 @@ class Giveaway: self.subtitle = subtitle self.duration = duration self.end_time = end_time + self.sponsor = sponsor # New sponsor field + self.game_url = game_url # Game store URL + self.game_info = game_info # Extracted game information self.participants = [] 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 @@ -1323,6 +1505,9 @@ class Giveaway: giveaway.num_winners = data.get("num_winners", 1) giveaway.title = data.get("title", "Unknown Giveaway") giveaway.subtitle = data.get("subtitle", "") + giveaway.sponsor = data.get("sponsor", None) # Restore sponsor + giveaway.game_url = data.get("game_url", None) # Restore game URL + giveaway.game_info = data.get("game_info", None) # Restore game info giveaway.duration = "restored" giveaway.end_time = datetime.now() # Already expired giveaway.participants = [] @@ -1344,6 +1529,9 @@ class Giveaway: "num_winners": self.num_winners, "title": self.title, "subtitle": self.subtitle, + "sponsor": self.sponsor, # Include sponsor in data + "game_url": self.game_url, # Include game URL + "game_info": self.game_info, # Include game info "winner_uuids": [str(uuid) for uuid in self.winner_uuids], "prize_uuid": str(self.prize_uuid), "game_key": self.game_key, @@ -1433,43 +1621,105 @@ class Giveaway: logger.error(f"Error completing giveaway process: {e}") @client.hybrid_command() -async def startgiveaway(ctx, platform: str, prize: str, num_winners: int, title: str, subtitle: str, duration: str): - """Creates a new giveaway, only available for admins.""" +async def startgiveaway(ctx, platform: str, prize: str, num_winners: int, title: str, subtitle: str, duration: str, sponsor: str = None, game_url: str = None): + """Creates a new giveaway, only available for admins. + + Parameters: + - platform: Gaming platform (Steam, Epic, etc.) + - prize: What's being given away + - num_winners: Number of winners to select + - title: Main giveaway title + - subtitle: Additional description + - duration: Duration (e.g. 1d, 30m, 2h) + - sponsor: Optional sponsor mention/name (e.g. @SimolZimol) + - game_url: Optional game store URL (Steam, Epic, etc.) for clickable link and auto-image + """ guild_id = ctx.guild.id user_data = load_user_data_sync(ctx.author.id, guild_id) if user_data["permission"] < 5: await ctx.send("You don't have permission to create a giveaway.") return + # Parse duration with more formats if duration.endswith("m"): minutes = int(duration[:-1]) end_time = datetime.now() + timedelta(minutes=minutes) + elif duration.endswith("h"): + hours = int(duration[:-1]) + end_time = datetime.now() + timedelta(hours=hours) elif duration.endswith("d"): days = int(duration[:-1]) end_time = datetime.now() + timedelta(days=days) else: - await ctx.send("Invalid duration. Please use 'm' for minutes or 'd' for days.") + await ctx.send("Invalid duration. Please use 'm' for minutes, 'h' for hours, or 'd' for days (e.g. 30m, 2h, 1d).") return + # Extract game information from URL if provided + game_info = None + if game_url: + game_info = await extract_game_info(game_url) + # Create new giveaway - giveaway = Giveaway(ctx, platform, prize, num_winners, title, subtitle, duration, end_time) + giveaway = Giveaway(ctx, platform, prize, num_winners, title, subtitle, duration, end_time, sponsor, game_url, game_info) giveaway_id = len(giveaways) + 1 giveaways[giveaway_id] = giveaway # Update the process data with the actual giveaway ID giveaway.update_process_data(giveaway_id) - button = Button(label="Participate", style=discord.ButtonStyle.green, custom_id=f"giveaway_{giveaway_id}") + # Create enhanced button + button = Button(label="๐ŸŽ‰ Join Giveaway", style=discord.ButtonStyle.green, custom_id=f"giveaway_{giveaway_id}", emoji="๐ŸŽ") view = View() view.add_item(button) unix_end_time = int(time.mktime(end_time.timetuple())) + # Enhanced embed design embed = discord.Embed( - title=title, - description=f"{subtitle}\n\nPrize: {prize}\nPlatform: {platform}\nNumber of winners: {num_winners}\nEnds ", - color=0x00ff00 + title=f"๐ŸŽ‰ {title}", + description=f"โœจ {subtitle}", + color=0xFFD700, # Gold color for premium look + timestamp=end_time ) - embed.set_footer(text=f"Giveaway ends at {end_time.strftime('%Y-%m-%d %H:%M:%S')}") + + # Game information with clickable link if available + if game_info and game_info.get('name'): + if game_url: + prize_text = f"**[{game_info['name']}]({game_url})**" + else: + prize_text = f"**{game_info['name']}**" + + # Add additional game details if available + if game_info.get('description'): + prize_text += f"\n*{game_info['description'][:100]}{'...' if len(game_info.get('description', '')) > 100 else ''}*" + else: + # Fallback to original prize text with URL if available + if game_url: + prize_text = f"**[{prize}]({game_url})**" + else: + prize_text = f"**{prize}**" + + # Main prize information + embed.add_field(name="๐ŸŽ Prize", value=prize_text, inline=True) + embed.add_field(name="๐ŸŽฎ Platform", value=f"**{platform}**", inline=True) + embed.add_field(name="๐Ÿ‘ฅ Winners", value=f"**{num_winners}**", inline=True) + + # Time information + embed.add_field(name="โฐ Ends", value=f"\n", inline=False) + + # Sponsor information if provided + if sponsor: + embed.add_field(name="๐Ÿ’ Sponsored by", value=f"**{sponsor}**", inline=False) + embed.set_footer(text=f"Giveaway ID: {giveaway_id} โ€ข Sponsored by {sponsor}") + else: + embed.set_footer(text=f"Giveaway ID: {giveaway_id} โ€ข Good luck!") + + # Set game image if available, otherwise use default + if game_info and game_info.get('image_url'): + embed.set_image(url=game_info['image_url']) + embed.set_thumbnail(url="https://cdn.discordapp.com/emojis/1028701098145587302.png") + else: + embed.set_thumbnail(url="https://cdn.discordapp.com/emojis/1028701098145587302.png") + await ctx.send(embed=embed, view=view) # Start the process manager if it's not already running @@ -1625,13 +1875,36 @@ async def on_interaction(interaction): if giveaway: if giveaway.is_finished(): - await interaction.response.send_message("This giveaway has already ended.", ephemeral=True) + # Enhanced ended message + ended_embed = discord.Embed( + title="โฐ Giveaway Ended", + description="This giveaway has already ended. Stay tuned for future giveaways!", + color=0xFF6B6B + ) + await interaction.response.send_message(embed=ended_embed, ephemeral=True) else: added = giveaway.add_participant(interaction.user) if added: - await interaction.response.send_message("You have successfully entered the giveaway!", ephemeral=True) + # Enhanced success message + success_embed = discord.Embed( + title="๐ŸŽ‰ Successfully Entered!", + description=f"You're now participating in **{giveaway.title}**!", + color=0x00FF00 + ) + success_embed.add_field(name="๐ŸŽ Prize", value=giveaway.prize, inline=True) + success_embed.add_field(name="๐Ÿ‘ฅ Participants", value=f"{len(giveaway.participants)}", inline=True) + success_embed.set_footer(text="Good luck! ๐Ÿ€") + await interaction.response.send_message(embed=success_embed, ephemeral=True) else: - await interaction.response.send_message("You're already participating in this giveaway.", ephemeral=True) + # Enhanced already participating message + already_embed = discord.Embed( + title="โ„น๏ธ Already Participating", + description=f"You're already entered in **{giveaway.title}**!", + color=0xFFB347 + ) + already_embed.add_field(name="๐Ÿ‘ฅ Current Participants", value=f"{len(giveaway.participants)}", inline=True) + already_embed.set_footer(text="Good luck! ๐Ÿ€") + await interaction.response.send_message(embed=already_embed, ephemeral=True) # Slash Commands und andere Interaktionen werden automatisch vom Framework verarbeitet def read_introduction():