import discord
from discord.ext import commands, tasks
from discord import app_commands
import sqlite3
import datetime
import zoneinfo
import asyncio
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix=»!», intents=intents)
— 1. CONFIGURACIÓN DE BASE DE DATOS LOCAL —
— CONFIGURACIÓN DE LA BASE DE DATOS SEPARADA DE ÍTEMS —
def iniciar_db_items():
# Crea un archivo completamente nuevo llamado items.db
conn = sqlite3.connect(«items.db»)
cursor = conn.cursor()
# Creación de la tabla de catálogo dentro de items.db
cursor.execute("""
CREATE TABLE IF NOT EXISTS catalogo_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nombre TEXT UNIQUE,
tipo TEXT,
uso TEXT,
rareza TEXT,
descripcion TEXT
)
""")
# Herramientas iniciales clasificadas por tipo, uso y rareza
items_iniciales = [
("Pico de Sangre Negra", "Herramienta", "Recolección Extrema", "Legendaria", "Extrae recursos a una velocidad asombrosa. Cubierto de una sustancia oscura."),
("Hacha de Metal Celestial", "Herramienta", "Recolección Alta", "Épica", "Forjada con meteoritos caídos del cielo. Muy duradera."),
("Pico de Acero Endurecido", "Herramienta", "Recolección Media", "Común", "Una herramienta confiable para cualquier exiliado establecido."),
("Cuchillo de Carnicero de Obsidian", "Herramienta", "Carnicería", "Épica", "Ideal para extraer la máxima cantidad de carne y pieles exóticas."),
("Porra de Hierro Reforzado", "Herramienta", "Sumisión", "Común", "Diseñada para dejar inconscientes a los thralls de nivel alto sin matarlos.")
]
cursor.executemany("""
INSERT OR IGNORE INTO catalogo_items (nombre, tipo, uso, rareza, descripcion)
VALUES (?, ?, ?, ?, ?)
""", items_iniciales)
conn.commit()
conn.close() def iniciar_db():
conn = sqlite3.connect(«personajes.db»)
cursor = conn.cursor()
cursor.execute(«»»
CREATE TABLE IF NOT EXISTS personajes (
user_id TEXT PRIMARY KEY,
nombre TEXT,
ubicacion TEXT,
colores TEXT,
raza TEXT,
religion TEXT,
historia TEXT
)
«»»)
# Nueva tabla para controlar las subastas activas
cursor.execute(«»»
CREATE TABLE IF NOT EXISTS subastas (
id INTEGER PRIMARY KEY AUTOINCREMENT,
objeto TEXT,
precio_actual INTEGER,
mejor_postor TEXT,
activa INTEGER,
tiempo_fin TEXT
)
«»»)
conn.commit()
conn.close()
🔍 ¡PEGAR AQUÍ LA NUEVA FUNCIÓN DE BÚSQUEDA FLEXIBLE!
def buscar_emoji_flexible(guild, texto_buscar):
if not guild or not guild.emojis:
return None
busqueda = texto_buscar.lower().replace(«-«, «»).replace(««, «»).strip() for emoji in guild.emojis: nombre_emoji = emoji.name.lower().replace(«-«, «»).replace(««, «»)
if busqueda in nombre_emoji:
return emoji
return None
— 2. SISTEMA DE HORA —
def obtener_horas():
try:
ahora_es = datetime.datetime.now(zoneinfo.ZoneInfo(«Europe/Madrid»))
ahora_mx = datetime.datetime.now(zoneinfo.ZoneInfo(«America/Mexico_City»))
except zoneinfo.ZoneInfoNotFoundError:
ahora_es = datetime.datetime.now()
ahora_mx = ahora_es – datetime.timedelta(hours=7)
formato = "%H:%M"
return f"⏰ **Hora Actual:**\n🇪🇸 **España:** {ahora_es.strftime(formato)}\n🇲🇽 **México:** {ahora_mx.strftime(formato)}" @tasks.loop(seconds=60)
async def anuncio_hora():
ahora = datetime.datetime.now()
if ahora.minute == 0:
for guild in bot.guilds:
channel = guild.system_channel or discord.utils.get(guild.text_channels, name=»🙌🏻┃bienvenidas»)
if channel:
try:
await channel.send(f»📢 Anuncio de Hora en Punto\n{obtener_horas()}»)
except Exception:
pass
— 3. FORMULARIO INTERACTIVO PARA CREAR O MODIFICAR ROL —
class FormularioRol(discord.ui.Modal, title=»Ficha de Personaje de Rol»):
def init(self, valores_previos=None):
super().init()
p_nombre = valores_previos[1] if valores_previos else «»
p_ubica = valores_previos[2] if valores_previos else «»
p_colores = valores_previos[3] if valores_previos else «»
p_raza_rel = f»{valores_previos[4]} / {valores_previos[5]}» if valores_previos else «»
p_hist = valores_previos[6] if valores_previos else «»
self.nombre = discord.ui.TextInput(label="Nombre del personaje", default=p_nombre, placeholder="Ej: Conan")
self.ubicacion = discord.ui.TextInput(label="Ubicación de la base", default=p_ubica, placeholder="Ej: Cuadrante C4")
self.colores = discord.ui.TextInput(label="Dos colores para tu clan", default=p_colores, placeholder="Ej: Negro y Rojo")
self.raza_religion = discord.ui.TextInput(label="Raza y Religión", default=p_raza_rel, placeholder="Ej: Cimerio / Crom")
self.historia = discord.ui.TextInput(label="Breve historia del personaje", default=p_hist, style=discord.TextStyle.paragraph, placeholder="Escribe el lore de tu personaje...")
self.add_item(self.nombre)
self.add_item(self.ubicacion)
self.add_item(self.colores)
self.add_item(self.raza_religion)
self.add_item(self.historia)
async def on_submit(self, interaction: discord.Interaction):
conn = sqlite3.connect("personajes.db")
cursor = conn.cursor()
datos_rr = self.raza_religion.value.split("/")
raza = datos_rr[0].strip() if len(datos_rr) > 0 else "Desconocida"
religion = datos_rr[1].strip() if len(datos_rr) > 1 else "No especificada"
cursor.execute("""
INSERT OR REPLACE INTO personajes (user_id, nombre, ubicacion, colores, raza, religion, historia)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (str(interaction.user.id), self.nombre.value, self.ubicacion.value, self.colores.value, raza, religion, self.historia.value))
conn.commit()
conn.close()
embed = discord.Embed(
title=f"📜 Ficha de Rol Guardada: {self.nombre.value}",
color=discord.Color.dark_orange()
)
embed.set_thumbnail(url=interaction.user.display_avatar.url)
embed.add_field(name="👤 Usuario", value=interaction.user.mention, inline=True)
embed.add_field(name="🌍 Raza", value=raza, inline=True)
embed.add_field(name="⛪ Religión", value=religion, inline=True)
embed.add_field(name="🏰 Base", value=self.ubicacion.value, inline=False)
embed.add_field(name="🎨 Colores del Clan", value=self.colores.value, inline=False)
embed.add_field(name="📖 Lore", value=self.historia.value, inline=False)
await interaction.response.send_message(content="✅ ¡Ficha registrada correctamente!", embed=embed) — 4. EVENTOS PRINCIPALES —
@bot.event
async def on_ready():
iniciar_db() # Sigue creando personajes.db
iniciar_db_items() # ¡NUEVO! Crea de forma separada items.db
print(f»¡Bot encendido con éxito como {bot.user}!»)
id_servidor = 1234591608855330847
guild = discord.Object(id=id_servidor)
try:
bot.tree.copy_global_to(guild=guild)
synced = await bot.tree.sync(guild=guild)
print(f"⚡ Sincronización realizada: {len(synced)} comandos cargados correctamente.")
except Exception as e:
print(f"Error al sincronizar comandos: {e}")
if not anuncio_hora.is_running():
anuncio_hora.start() @bot.event
async def on_member_join(member):
# 1. Asignar el rol @Recien llegado
role = discord.utils.get(member.guild.roles, name=»Recien llegado»)
if role:
try:
await member.add_roles(role)
except discord.Forbidden:
print(«Error de permisos al asignar el rol.»)
# 2. Buscar canal de bienvenidas
channel = member.guild.system_channel
if channel is None:
channel = discord.utils.get(member.guild.text_channels, name="🙌🏻┃bienvenidas")
if channel:
# 🔍 BÚSQUEDA AUTOMÁTICA Y FLEXIBLE DE EMOJIS PERSONALIZADOS
e_saludo = buscar_emoji_flexible(member.guild, "saludo")
e_scroll = buscar_emoji_flexible(member.guild, "scroll")
e_shield = buscar_emoji_flexible(member.guild, "shield")
# Iconos de respaldo en texto/teclado si no encuentra los personalizados
i_saludo = e_saludo if e_saludo else "👋"
i_scroll = e_scroll if e_scroll else "📜"
i_shield = e_shield if e_shield else "🛡️"
# Crear la tarjeta (Embed) de color amarillo/dorado utilizando los nuevos iconos
embed = discord.Embed(
title=f"{i_saludo} ¡Un nuevo exiliado ha llegado!",
description=f"🎉 Bienvenido/a {member.mention} a **Conan Exiles II: LEG RENACIMIENTO** 🌅\n\n"
f"{i_scroll} **Primeros pasos**\n"
f"Lee las reglas en <#1369746613152780426>, preséntate en "
f"<#1369742721908080670>, y únete al lore en <#1236757246528983301>. "
f"Consulta <#1395177037181878385> si tienes dudas.\n\n"
f"**¿Vienes a jugar en PC o XBOX?**\n"
f"El servidor de PC pronto estará disponible.\n\n"
f"Usa el comando `/server` para saber cómo conectarte a nuestro servidor de XBOX.\n\n"
f"{i_shield} **Rol asignado**\n"
f"Se te ha otorgado el rol: {role.mention if role else '@Recien llegado'}",
color=discord.Color.from_rgb(255, 170, 0)
)
# Imagen estática fija en la esquina superior derecha (El emoji webp que configuramos antes)
embed.set_thumbnail(url="https://discordapp.com")
# Imagen grande al final del recuadro (El avatar dinámico del usuario que entra)
embed.set_image(url=member.display_avatar.url)
# Enviar el Embed al canal de bienvenidas
await channel.send(embed=embed) — 5. COMANDOS DE BARRA DIAGONAL (/) —
@bot.tree.command(name=»server», description=»Muestra los datos de conexión del servidor de juego»)
async def server(interaction: discord.Interaction):
# El bot busca cualquier emoji que contenga la palabra «conan» (no importa mayúsculas o guiones)
emoji_conan = buscar_emoji_flexible(interaction.guild, «conan»)
# Si encuentra el emoji lo usa, si no, pone un diamante azul por defecto
icono = emoji_conan if emoji_conan else "🔹"
await interaction.response.send_message(
f"{icono} **Datos de Conexión:**\n"
f"🔹 En la lista de servidores busca **\"LEG RENACIMIENTO\"**",
ephemeral=True
) @bot.tree.command(name=»ticket», description=»Abre un canal de soporte privado con la administración»)
async def ticket(interaction: discord.Interaction):
guild = interaction.guild
categoria_id = 1518946115712450722
categoria = discord.utils.get(guild.categories, id=categoria_id)
if not categoria:
await interaction.response.send_message("❌ Error: No se encontró la categoría de soporte.", ephemeral=True)
return
nombre_canal = f"ticket-{interaction.user.name.lower()}"
overwrites = {
guild.default_role: discord.PermissionOverwrite(view_channel=False),
interaction.user: discord.PermissionOverwrite(view_channel=True, send_messages=True, read_message_history=True),
guild.me: discord.PermissionOverwrite(view_channel=True, send_messages=True)
}
ticket_channel = await guild.create_text_channel(name=nombre_canal, category=categoria, overwrites=overwrites)
embed_preguntas = discord.Embed(
title="🎫 Ticket de Soporte Creado",
description=f"Hola {interaction.user.mention}, un administrador te atenderá pronto.\n"
f"Para agilizar el proceso, responde detalladamente a estas preguntas:\n\n"
f"1️⃣ **¿Cuál es el motivo de tu consulta o problema?**\n"
f"2️⃣ **Si aplica, ¿en qué plataforma juegas (PC o XBOX)?**\n"
f"3️⃣ **Adjunta capturas de pantalla o pruebas si dispones de ellas.**\n\n"
f"🔒 *Para cerrar este ticket, un administrador deberá usar `/cerrar`.*",
color=discord.Color.red()
)
await ticket_channel.send(embed=embed_preguntas)
await interaction.response.send_message(f"✅ Tu ticket ha sido creado en {ticket_channel.mention}", ephemeral=True) @bot.tree.command(name=»cerrar», description=»Cierra y elimina el ticket de un usuario específico (Solo Admins)»)
@app_commands.describe(usuario=»Menciona al usuario (@usuario) o selecciónalo de la lista flotante»)
@commands.has_permissions(administrator=True)
async def cerrar(interaction: discord.Interaction, usuario: discord.Member):
nombre_canal_esperado = f»ticket-{usuario.name.lower()}»
canal_ticket = discord.utils.get(interaction.guild.text_channels, name=nombre_canal_esperado)
if canal_ticket:
await interaction.response.send_message(f"🔒 Cerrando y eliminando el canal {canal_ticket.mention} en 5 segundos...", ephemeral=True)
await asyncio.sleep(5)
await canal_ticket.delete()
else:
await interaction.response.send_message(f"❌ No se encontró ningún canal activo llamado `{nombre_canal_esperado}` para {usuario.mention}.", ephemeral=True) @bot.tree.command(name=»rol», description=»Registra tu personaje de rol (Solo se permite una vez)»)
async def rol(interaction: discord.Interaction):
conn = sqlite3.connect(«personajes.db»)
cursor = conn.cursor()
cursor.execute(«SELECT * FROM personajes WHERE user_id = ?», (str(interaction.user.id),))
datos = cursor.fetchone()
conn.close()
if datos:
await interaction.response.send_message(
f"❌ Ya tienes un personaje registrado como **{datos[1]}**. Solicita una edición al Staff.",
ephemeral=True
)
else:
await interaction.response.send_modal(FormularioRol()) @bot.tree.command(name=»buscar_item», description=»Busca herramientas o ítems en la base de datos del servidor»)
@app_commands.describe(nombre=»Escribe parte del nombre del objeto que quieres buscar»)
1. FUNCIÓN INTERNA DE AUTOCOMPLETADO (Debe ir arriba del comando obligatoriamente)
async def item_autocomplete(interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
conn = sqlite3.connect(«items.db»)
cursor = conn.cursor()
# Filtramos los ítems que contengan lo que el usuario escribe en tiempo real
cursor.execute("""
SELECT nombre FROM catalogo_items
WHERE nombre LIKE ?
LIMIT 25
""", (f"%{current}%",))
resultados = cursor.fetchall()
conn.close()
# Retornamos la lista de sugerencias limpia a la interfaz de Discord
return [
app_commands.Choice(name=row[0], value=row[0])
for row in resultados
] 2. COMANDO /BUSCAR_ITEM CORREGIDO CON PARÁMETROS ALINEADOS
@bot.tree.command(name=»buscar_item», description=»Busca herramientas o ítems en el catálogo del servidor»)
@app_commands.describe(item_a_buscar=»Empieza a escribir el nombre del ítem y selecciónalo de la lista»)
@app_commands.autocomplete(item_a_buscar=item_autocomplete) # Parámetro alineado con la función de abajo
async def buscar_item(interaction: discord.Interaction, item_a_buscar: str): # Nombre unificado
conn = sqlite3.connect(«items.db»)
cursor = conn.cursor()
cursor.execute("""
SELECT nombre, tipo, uso, rareza, description
FROM catalogo_items
WHERE nombre = ?
""", (item_a_buscar,))
item = cursor.fetchone()
conn.close()
if not item:
await interaction.response.send_message(
f"❌ No se encontró ningún ítem exacto llamado **\"{item_a_buscar}\"**. Por favor, usa las sugerencias al escribir.",
ephemeral=True
)
return
i_nombre, i_tipo, i_uso, i_rareza, i_desc = item
# Colores automáticos según la rareza
color_rareza = discord.Color.default()
if i_rareza == "Legendaria": color_rareza = discord.Color.purple()
elif i_rareza == "Épica": color_rareza = discord.Color.magenta()
elif i_rareza == "Común": color_rareza = discord.Color.blue()
embed = discord.Embed(
title=f"📦 Catálogo LEG: {i_nombre}",
description=i_desc,
color=color_rareza
)
embed.add_field(name="📋 Tipo", value=i_tipo, inline=True)
embed.add_field(name="⚙️ Uso Principal", value=i_uso, inline=True)
embed.add_field(name="💎 Rareza", value=i_rareza, inline=True)
# Decoración opcional con emoji flexible
e_item = buscar_emoji_flexible(interaction.guild, "item")
if e_item: embed.set_thumbnail(url=e_item.url)
await interaction.response.send_message(embed=embed) COMANDO /MODIFICAR_PERFIL CORREGIDO Y SEGURO (SÓLO PARA STAFF)
@bot.tree.command(name=»modificar_perfil», description=»Modifica los datos del personaje de un exiliado (Solo Administradores)»)
@app_commands.describe(usuario=»Selecciona al usuario al que deseas editarle la ficha de rol»)
@app_commands.checks.has_permissions(administrator=True)
async def modificar_perfil(interaction: discord.Interaction, usuario: discord.Member):
conn = sqlite3.connect(«personajes.db»)
cursor = conn.cursor()
cursor.execute(«SELECT * FROM personajes WHERE user_id = ?», (str(usuario.id),))
datos = cursor.fetchone()
conn.close()
if not datos:
await interaction.response.send_message(
f"❌ {usuario.mention} aún no tiene un personaje registrado con `/rol`.",
ephemeral=True
)
else:
formulario = FormularioRol(valores_previos=datos)
async def nuevo_on_submit(interact: discord.Interaction):
conn_db = sqlite3.connect("personajes.db")
cursor_db = conn_db.cursor()
datos_rr = formulario.raza_religion.value.split("/")
raza = datos_rr[0].strip() if len(datos_rr) > 0 else "Desconocida"
religion = datos_rr[1].strip() if len(datos_rr) > 1 else "No especificada"
cursor_db.execute("""
INSERT OR REPLACE INTO personajes (user_id, nombre, ubicacion, colores, raza, religion, historia)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (str(usuario.id), formulario.nombre.value, formulario.ubicacion.value, formulario.colores.value, raza, religion, formulario.historia.value))
conn_db.commit()
conn_db.close()
embed = discord.Embed(
title=f"📝 Ficha Modificada por el Staff: {formulario.nombre.value}",
color=discord.Color.dark_red()
)
embed.set_thumbnail(url=usuario.display_avatar.url)
embed.add_field(name="👤 Exiliado", value=usuario.mention, inline=True)
embed.add_field(name="🌍 Raza", value=raza, inline=True)
embed.add_field(name="⛪ Religión", value=religion, inline=True)
embed.add_field(name="🏰 Base", value=formulario.ubicacion.value, inline=False)
embed.add_field(name="🎨 Colores del Clan", value=formulario.colores.value, inline=False)
embed.add_field(name="📖 Lore Actualizado", value=formulario.historia.value, inline=False)
await interact.response.send_message(content=f"✅ ¡La ficha de {usuario.mention} ha sido modificada con éxito!", embed=embed)
formulario.on_submit = nuevo_on_submit
await interaction.response.send_modal(formulario) @modificar_perfil.error
async def modificar_perfil_error(interaction: discord.Interaction, error: app_commands.AppCommandError):
if isinstance(error, app_commands.errors.MissingPermissions):
await interaction.response.send_message(«⛔ No tienes permisos de Administrador para usar este comando.», ephemeral=True)
@bot.tree.command(name=»ficha_pj», description=»Muestra la ficha de rol de un exiliado»)
@app_commands.describe(usuario=»El exiliado del que quieres ver la ficha (vacío para ver la tuya)»)
async def ficha_pj(interaction: discord.Interaction, usuario: discord.Member = None):
target_user = usuario or interaction.user
conn = sqlite3.connect("personajes.db")
cursor = conn.cursor()
cursor.execute("SELECT * FROM personajes WHERE user_id = ?", (str(target_user.id),))
datos = cursor.fetchone()
conn.close()
if datos:
embed = discord.Embed(
title=f"📜 Ficha de Rol: {datos[1]}",
color=discord.Color.dark_orange()
)
embed.set_thumbnail(url=target_user.display_avatar.url)
embed.add_field(name="👤 Exiliado", value=target_user.mention, inline=True)
embed.add_field(name="🌍 Raza", value=datos[4], inline=True)
embed.add_field(name="⛪ Religión", value=datos[5], inline=True)
embed.add_field(name="🏰 Ubicación de la Base", value=datos[2], inline=False)
embed.add_field(name="🎨 Colores del Clan", value=datos[3], inline=False)
embed.add_field(name="📖 Lore / Historia", value=datos[6], inline=False)
await interaction.response.send_message(embed=embed)
else:
await interaction.response.send_message(f"❌ {target_user.mention} no tiene un personaje registrado.", ephemeral=True) @bot.tree.command(name=»hora», description=»Muestra la hora actual de España y México»)
async def hora(interaction: discord.Interaction):
await interaction.response.send_message(obtener_horas())
— 6. SISTEMA DE SUBASTAS AVANZADO —
Comando para iniciar una subasta (Solo Staff)
@bot.tree.command(name=»subastar», description=»Inicia una subasta oficial en el servidor (Solo Administradores)»)
@app_commands.describe(objeto=»El ítem o beneficio a subastar», precio_inicio=»Precio de salida», minutos=»Duración en minutos»)
@app_commands.checks.has_permissions(administrator=True)
async def subastar(interaction: discord.Interaction, objeto: str, precio_inicio: int, minutos: int):
conn = sqlite3.connect(«personajes.db»)
cursor = conn.cursor()
# Verificar si ya hay una subasta corriendo
cursor.execute("SELECT id FROM subastas WHERE activa = 1")
if cursor.fetchone():
await interaction.response.send_message("❌ Ya hay una subasta activa en este momento. Espera a que termine.", ephemeral=True)
conn.close()
return
# Calcular cuándo terminará la subasta
tiempo_fin = datetime.datetime.now() + datetime.timedelta(minutes=minutos)
tiempo_fin_str = tiempo_fin.strftime("%Y-%m-%d %H:%M:%S")
# Registrar la subasta en la DB
cursor.execute("""
INSERT INTO subastas (objeto, precio_actual, mejor_postor, activa, tiempo_fin)
VALUES (?, ?, 'Nadie', 1, ?)
""", (objeto, precio_inicio, tiempo_fin_str))
conn.commit()
conn.close()
# Buscar emoji personalizado para decorar
e_subasta = buscar_emoji_flexible(interaction.guild, "subasta")
i_subasta = e_subasta if e_subasta else "🔨"
embed = discord.Embed(
title=f"{i_subasta} ¡NUEVO ITEM DISPONIBLE EN LA CASA DE SUBASTAS! Propietario: {interaction.user.name}",
description=f"⚔️ **Objeto:** {objeto}\n"
f"💰 **Precio de salida:** {precio_inicio} monedas\n"
f"⏳ **Duración:** {minutos} minutos\n\n"
f"👉 Usa el comando `/pujar` para ofrecer más dinero.",
color=discord.Color.gold()
)
await interaction.response.send_message(embed=embed)
# Programar el cierre automático en segundo plano
await asyncio.sleep(minutos * 60)
await finalizar_subasta_automatica(interaction.guild, objeto) Función interna para cerrar la subasta en la DB y anunciar al ganador
async def finalizar_subasta_automatica(guild, objeto_nombre):
conn = sqlite3.connect(«personajes.db»)
cursor = conn.cursor()
cursor.execute(«SELECT precio_actual, mejor_postor FROM subastas WHERE objeto = ? AND activa = 1», (objeto_nombre,))
res = cursor.fetchone()
if res:
precio, ganador = res
cursor.execute("UPDATE subastas SET activa = 0 WHERE objeto = ? AND activa = 1", (objeto_nombre,))
conn.commit()
channel = guild.system_channel or discord.utils.get(guild.text_channels, name="🙌🏻┃bienvenidas")
if channel:
if ganador == "Nadie":
await channel.send(f"🔨 **Subasta finalizada:** El objeto **{objeto_nombre}** quedó desierto porque nadie pujó.")
else:
await channel.send(f"🎉 **¡SUBASTA CONCLUIDA!** 🎉\nEl objeto **{objeto_nombre}** ha sido vendido a {ganador} por un total de **{precio} monedas**. ¡Enhorabuena!")
conn.close() Comando para que los usuarios pujen
@bot.tree.command(name=»pujar», description=»Ofrece una cantidad de dinero mayor en la subasta activa»)
@app_commands.describe(cantidad=»Monedas totales que ofreces»)
async def pujar(interaction: discord.Interaction, cantidad: int):
conn = sqlite3.connect(«personajes.db»)
cursor = conn.cursor()
cursor.execute(«SELECT objeto, precio_actual, tiempo_fin FROM subastas WHERE activa = 1»)
subasta = cursor.fetchone()
if not subasta:
await interaction.response.send_message("❌ No hay ninguna subasta activa en la que puedas pujar.", ephemeral=True)
conn.close()
return
objeto, precio_actual, tiempo_fin_str = subasta
# Verificar si el tiempo ya expiró
tiempo_fin = datetime.datetime.strptime(tiempo_fin_str, "%Y-%m-%d %H:%M:%S")
if datetime.datetime.now() > tiempo_fin:
await interaction.response.send_message("❌ Esta subasta ya ha terminado.", ephemeral=True)
conn.close()
return
# Validar que la oferta sea mayor a la actual
if cantidad <= precio_actual:
await interaction.response.send_message(f"❌ Tu puja debe ser mayor que la puja actual (**{precio_actual} monedas**).", ephemeral=True)
conn.close()
return
# Actualizar el mejor postor
cursor.execute("UPDATE subastas SET precio_actual = ?, mejor_postor = ? WHERE activa = 1", (cantidad, interaction.user.mention))
conn.commit()
conn.close()
await interaction.response.send_message(f"📈 ¡{interaction.user.mention} ha pujado **{cantidad} monedas** por **{objeto}**!") Comando para ver el estado de la subasta activa
@bot.tree.command(name=»subasta_actual», description=»Muestra el estado de la subasta en curso»)
async def subasta_actual(interaction: discord.Interaction):
conn = sqlite3.connect(«personajes.db»)
cursor = conn.cursor()
cursor.execute(«SELECT objeto, precio_actual, mejor_postor, tiempo_fin FROM subastas WHERE activa = 1»)
subasta = cursor.fetchone()
conn.close()
if not subasta:
await interaction.response.send_message("💤 Actualmente no hay ninguna subasta activa en el reino.", ephemeral=True)
return
objeto, precio_actual, mejor_postor, tiempo_fin_str = subasta
embed = discord.Embed(
title="🔨 Subasta en Curso",
description=f"📦 **Objeto:** {objeto}\n"
f"💰 **Puja Máxima:** {precio_actual} monedas\n"
f"👤 **Líder actual:** {mejor_postor}\n"
f"📆 **Finaliza el:** `{tiempo_fin_str}`",
color=discord.Color.blue()
)
await interaction.response.send_message(embed=embed) bot.run(»)