Hilmany / cogs /level.py
HilmanBey's picture
Upload 64 files
cbb05ec verified
Raw
History Blame Contribute Delete
10.4 kB
import discord
from discord.ext import commands
from discord import app_commands
from datetime import datetime
from database import Database
import random
CYBER_BLUE = discord.Color.from_rgb(52, 152, 219)
CYBER_GREEN = discord.Color.from_rgb(46, 204, 113)
CYBER_GOLD = discord.Color.from_rgb(241, 196, 15)
class Level(commands.Cog):
def __init__(self, bot):
self.bot = bot
# Cooldown: {user_id: last_msg_ts}
self._xp_cooldown = {}
self.COOLDOWN_SECONDS = 30
def _xp_for_level(self, level, difficulty=100):
return 5 * (level ** 2) + 50 * level + 100 - level * difficulty // 10
def _level_from_xp(self, xp, difficulty=100):
level = 0
while xp >= self._xp_for_level(level + 1, difficulty):
level += 1
xp -= self._xp_for_level(level, difficulty)
return level, xp
async def _add_xp(self, member: discord.Member, xp_add: int):
guild_id = member.guild.id
user_id = member.id
row = await Database.fetch_one(
"SELECT * FROM seviye WHERE guild_id = ? AND user_id = ?",
(guild_id, user_id)
)
if not row:
await Database.execute(
"INSERT INTO seviye (guild_id, user_id, xp, seviye) VALUES (?, ?, ?, ?)",
(guild_id, user_id, 0, 0)
)
row = await Database.fetch_one(
"SELECT * FROM seviye WHERE guild_id = ? AND user_id = ?",
(guild_id, user_id)
)
new_xp = row['xp'] + xp_add
settings = await Database.fetch_one("SELECT * FROM seviye_ayarlar WHERE guild_id = ?", (guild_id,))
difficulty = settings['zorluk'] if settings and settings.get('zorluk') else 100
old_level = row['seviye']
new_level = self._level_from_xp(new_xp, difficulty)[0]
await Database.execute(
"UPDATE seviye SET xp = ?, seviye = ? WHERE guild_id = ? AND user_id = ?",
(new_xp, new_level, guild_id, user_id)
)
if new_level > old_level:
# Level up bildirimi
kanal_id = settings['mesaj_kanal_id'] if settings and settings.get('mesaj_kanal_id') else 0
kanal = member.guild.get_channel(kanal_id) if kanal_id else None
embed = discord.Embed(
title="🎉 Seviye Atlandı!",
description=f"Tebrikler {member.mention}! **Seviye {new_level}**'e ulaştın! 🎊",
color=CYBER_GOLD,
timestamp=datetime.now()
)
if kanal:
try:
await kanal.send(embed=embed)
except:
pass
# Rol ödülü var mı kontrol et
odul = await Database.fetch_one(
"SELECT rol_id FROM seviye_oduller WHERE guild_id = ? AND seviye = ?",
(guild_id, new_level)
)
if odul:
rol = member.guild.get_role(odul['rol_id'])
if rol:
try:
await member.add_roles(rol, reason=f"Seviye {new_level} ödülü")
except:
pass
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
if message.author.bot or not message.guild:
return
if not await Database.modul_aktif_mi(message.guild.id, "Level"):
return
settings = await Database.fetch_one("SELECT aktif FROM seviye_ayarlar WHERE guild_id = ?", (message.guild.id,))
if settings and settings.get('aktif') == 0:
return
# Cooldown kontrolü
import time
now = time.time()
last = self._xp_cooldown.get(message.author.id, 0)
if now - last < self.COOLDOWN_SECONDS:
return
self._xp_cooldown[message.author.id] = now
xp_gain = random.randint(15, 25)
await self._add_xp(message.author, xp_gain)
@commands.hybrid_command(name="seviye", description="Senin veya başka bir üyenin seviye kartını gösterir.")
@app_commands.describe(uye="Seviyesine bakılacak üye")
async def seviye(self, ctx: commands.Context, uye: discord.Member = None):
if ctx.interaction:
await ctx.defer()
target = uye or ctx.author
row = await Database.fetch_one(
"SELECT * FROM seviye WHERE guild_id = ? AND user_id = ?",
(ctx.guild.id, target.id)
)
if not row:
await ctx.send(f"ℹ️ {target.mention} henüz seviye verisine sahip değil.")
return
settings = await Database.fetch_one("SELECT * FROM seviye_ayarlar WHERE guild_id = ?", (ctx.guild.id,))
difficulty = settings['zorluk'] if settings and settings.get('zorluk') else 100
level = row['seviye']
xp = row['xp']
xp_for_current = self._xp_for_level(level, difficulty)
xp_for_next = self._xp_for_level(level + 1, difficulty)
xp_needed = xp_for_next - xp_for_current
xp_progress = xp - xp_for_current
progress_pct = int((xp_progress / max(xp_needed, 1)) * 100)
bar_size = 20
filled = int((xp_progress / max(xp_needed, 1)) * bar_size)
bar = "█" * filled + "░" * (bar_size - filled)
# Sıralama hesapla
all_users = await Database.fetch_all(
"SELECT user_id, xp FROM seviye WHERE guild_id = ? ORDER BY xp DESC",
(ctx.guild.id,)
)
rank = 1
for i, u in enumerate(all_users, 1):
if u['user_id'] == target.id:
rank = i
break
embed = discord.Embed(
title=f"🏆 Seviye Kartı - {target.display_name}",
color=CYBER_GOLD,
timestamp=datetime.now()
)
embed.set_thumbnail(url=target.display_avatar.url)
embed.add_field(name="Seviye", value=f"**{level}**", inline=True)
embed.add_field(name="Toplam XP", value=f"**{xp}**", inline=True)
embed.add_field(name="Sıralama", value=f"**#{rank}**", inline=True)
embed.add_field(
name=f"İlerleme ({progress_pct}%)",
value=f"`{bar}`\n{xp_progress}/{xp_needed} XP",
inline=False
)
await ctx.send(embed=embed)
@commands.hybrid_command(name="seviye-ayarla", description="Seviye sistemi ayarlarını yapar.")
@commands.has_permissions(administrator=True)
@app_commands.describe(
mesaj_kanali="Seviye atladığında bildirim gönderilecek kanal",
zorluk="Zorluk çarpanı (örn: 100 - ne kadar yüksek o kadar yavaş ilerleme)",
aktif="Seviye sistemi aktif mi? (1=Açık, 0=Kapalı)"
)
async def seviye_ayarla(self, ctx: commands.Context, mesaj_kanali: discord.TextChannel = None, zorluk: int = 100, aktif: int = 1):
if ctx.interaction:
await ctx.defer()
kanal_id = mesaj_kanali.id if mesaj_kanali else 0
await Database.execute(
"""INSERT OR REPLACE INTO seviye_ayarlar (guild_id, mesaj_kanal_id, aktif, zorluk)
VALUES (?, ?, ?, ?)""",
(ctx.guild.id, kanal_id, aktif, zorluk)
)
await ctx.send(f"✅ Seviye sistemi ayarlandı! Aktif: **{'Açık' if aktif else 'Kapalı'}**, Zorluk: **{zorluk}**")
@commands.hybrid_command(name="seviye-ödül-ekle", description="Belirli bir seviyeye ulaşınca verilecek rol ödülü ekler.")
@commands.has_permissions(administrator=True)
@app_commands.describe(seviye="Hedef seviye", rol="Verilecek rol")
async def seviye_odul_ekle(self, ctx: commands.Context, seviye: int, rol: discord.Role):
if ctx.interaction:
await ctx.defer()
await Database.execute(
"INSERT OR REPLACE INTO seviye_oduller (guild_id, seviye, rol_id) VALUES (?, ?, ?)",
(ctx.guild.id, seviye, rol.id)
)
await ctx.send(f"✅ Seviye **{seviye}**'e ulaşanlara **{rol.mention}** rolü verilecek.")
@commands.hybrid_command(name="seviye-ödül-sil", description="Bir seviye ödülünü siler.")
@commands.has_permissions(administrator=True)
@app_commands.describe(seviye="Ödül silinecek seviye")
async def seviye_odul_sil(self, ctx: commands.Context, seviye: int):
if ctx.interaction:
await ctx.defer()
await Database.execute(
"DELETE FROM seviye_oduller WHERE guild_id = ? AND seviye = ?",
(ctx.guild.id, seviye)
)
await ctx.send(f"✅ Seviye **{seviye}** ödülü silindi.")
@commands.hybrid_command(name="seviye-sıralama", description="Sunucudaki en yüksek seviyeli üyeleri gösterir.")
async def seviye_siralama(self, ctx: commands.Context):
if ctx.interaction:
await ctx.defer()
records = await Database.fetch_all(
"SELECT user_id, xp, seviye FROM seviye WHERE guild_id = ? ORDER BY xp DESC LIMIT 10",
(ctx.guild.id,)
)
if not records:
await ctx.send("ℹ️ Henüz seviye verisi bulunmamaktadır.")
return
embed = discord.Embed(title="🏆 Seviye Sıralaması", color=CYBER_GOLD, timestamp=datetime.now())
desc = ""
for i, r in enumerate(records, 1):
member = ctx.guild.get_member(r['user_id'])
name = member.mention if member else f"ID: {r['user_id']}"
emoji = "🥇" if i == 1 else "🥈" if i == 2 else "🥉" if i == 3 else f"#{i}"
desc += f"{emoji} {name} — Seviye **{r['seviye']}** ({r['xp']} XP)\n"
embed.description = desc
await ctx.send(embed=embed)
@commands.hybrid_command(name="seviye-sıfırla", description="Bir üyenin seviyesini sıfırlar.")
@commands.has_permissions(administrator=True)
@app_commands.describe(uye="Seviyesi sıfırlanacak üye")
async def seviye_sifirla(self, ctx: commands.Context, uye: discord.Member):
if ctx.interaction:
await ctx.defer()
await Database.execute(
"UPDATE seviye SET xp = 0, seviye = 0 WHERE guild_id = ? AND user_id = ?",
(ctx.guild.id, uye.id)
)
await ctx.send(f"✅ {uye.mention} kullanıcısının seviyesi sıfırlandı.")
async def setup(bot):
await bot.add_cog(Level(bot))