# cogs/drops.py import discord from discord.ext import commands import logging from services.gacha_service import GachaService from utils.cdn import get_or_create_card_url from utils.code_converter import encode_id from utils.generators.factory import generate_card_factory # ⚡ GLOBAL COOLDOWN ENGINE from utils.cooldown import check_and_apply_cooldown logger = logging.getLogger(__name__) # 👇 PASTE YOUR 5 IMGBB/DISCORD GIF URLS HERE SUMMON_ANIMATIONS = { "UR": "https://i.ibb.co/yFWSmJNG/ezgif-7031fd259bcfbd7e.gif", "SSR": "https://i.ibb.co/WppwQXWj/In-Shot-20260410-175647573.gif", "SR": "https://i.ibb.co/RMLxvMc/In-Shot-20260410-185023687.gif", "R": "https://i.ibb.co/pBYRtgjX/In-Shot-20260410-180010137.gif", "C": "https://i.ibb.co/qL9KKxRw/In-Shot-20260410-184700192.gif" } class DropsCog(commands.Cog): def __init__(self, bot): self.bot = bot @commands.Cog.listener() async def on_message(self, message: discord.Message): if message.author.bot: return if message.content.strip().lower() == "sp": # ⚡ INJECT GLOBAL COOLDOWN & MODERATION CHECKS HERE is_admin = getattr(message.author, "guild_permissions", None) and message.author.guild_permissions.administrator if not is_admin: from database.db import db async with db.pool.acquire() as conn: is_banned = await conn.fetchval("SELECT is_banned FROM users WHERE user_id = $1", message.author.id) if is_banned: return # Silently ignore banned users so they don't know the bot is online remaining = check_and_apply_cooldown(message.author.id) if remaining > 0: await message.channel.send( f"⏳ {message.author.mention}, please wait **{remaining:.1f}s** before commanding the bot again.", delete_after=5.0 ) return try: # 1. Hit the database INSTANTLY card = await GachaService.process_drop(message.author.id) # 2. Generate a hype message and fetch the correct GIF based on rarity rarity = card['rarity'] anim_url = SUMMON_ANIMATIONS.get(rarity, SUMMON_ANIMATIONS["C"]) if rarity == "UR": hype_text = "🟥 **A MYTHIC ANOMALY DETECTED!** Reality is tearing apart..." embed_color = discord.Color.red() elif rarity == "SSR": hype_text = "🟨 **A LEGENDARY SIGNAL!** Golden light pierces the void..." embed_color = discord.Color.gold() elif rarity == "SR": hype_text = "🟪 **AN EPIC PRESENCE!** Purple energy gathers..." embed_color = discord.Color.purple() elif rarity == "R": hype_text = "🟦 **A RARE SIGNAL!** Blue sparks ignite..." embed_color = discord.Color.blue() else: hype_text = "⬜ *A common soul answers your call...*" embed_color = discord.Color.light_grey() # 3. Build the suspense embed with the dynamic GIF temp_embed = discord.Embed( title="✨ Materializing Vanguard...", description=hype_text, color=embed_color ) temp_embed.set_image(url=anim_url) # Send the animation instantly temp_msg = await message.reply(embed=temp_embed, mention_author=False) # 4. Do the heavy CPU rendering in the background card_file = await generate_card_factory( image_url=card['image_url'], char_name=card['name'], print_num=card['print_num'], rarity=card['rarity'], element=card['element'] ) card_code = encode_id(card['instance_id']) # 5. Build the final reveal final_embed = discord.Embed( title=f"🎉 {message.author.display_name} dropped {card['name']}!", color=embed_color ) final_embed.add_field(name="Rarity", value=rarity, inline=True) final_embed.add_field(name="Element", value=card['element'] or "None", inline=True) final_embed.add_field(name="Series", value=card.get('series', 'Unknown') or "Unknown", inline=True) final_embed.add_field(name="Card Code", value=f"`{card_code}`", inline=True) # Attach the finished card image final_embed.set_image(url=f"attachment://{card_file.filename}") # 6. EDIT the suspense message await temp_msg.edit(embed=final_embed, attachments=[card_file]) # 7. Backup to Discord CDN invisibly async def backup_to_cdn(): try: await get_or_create_card_url( bot=self.bot, instance_id=card['instance_id'], image_url=card['image_url'], char_name=card['name'], print_num=card['print_num'], rarity=card['rarity'], element=card['element'] ) except Exception as e: logger.error(f"Background CDN upload failed for {card['instance_id']}: {e}") self.bot.loop.create_task(backup_to_cdn()) except ValueError as e: await message.channel.send(f"{message.author.mention} {str(e)}") except Exception as e: logger.error(f"Drop System Error: {e}", exc_info=True) error_embed = discord.Embed(title="⚠️ System Error", description="An unexpected error occurred during the drop.", color=discord.Color.red()) try: await temp_msg.edit(embed=error_embed, attachments=[]) except: await message.reply(embed=error_embed, mention_author=False) async def setup(bot): await bot.add_cog(DropsCog(bot))