95 lines
3.2 KiB
Python
95 lines
3.2 KiB
Python
import os
|
|
import discord
|
|
from discord.ext import commands, tasks
|
|
from dotenv import load_dotenv
|
|
from datetime import datetime, timedelta
|
|
import asyncio
|
|
from typing import Dict, Set
|
|
|
|
# Load environment variables
|
|
load_dotenv()
|
|
|
|
# Bot configuration
|
|
intents = discord.Intents.default()
|
|
intents.message_content = True
|
|
intents.members = True
|
|
intents.voice_states = True
|
|
|
|
bot = commands.Bot(command_prefix='!', intents=intents)
|
|
|
|
# Store user cooldowns and experience points
|
|
user_cooldowns: Dict[int, datetime] = {}
|
|
user_exp_points: Dict[int, int] = {}
|
|
voice_time: Dict[int, datetime] = {}
|
|
active_voice_users: Set[int] = set()
|
|
|
|
# Constants
|
|
CHAT_EXP_POINTS = 1
|
|
VOICE_EXP_POINTS_PER_MINUTE = 2
|
|
CHAT_COOLDOWN = 60 # seconds
|
|
|
|
@bot.event
|
|
async def on_ready():
|
|
print(f'{bot.user} has connected to Discord!')
|
|
update_voice_exp.start()
|
|
|
|
@bot.event
|
|
async def on_message(message):
|
|
if message.author.bot:
|
|
return
|
|
|
|
# Handle chat experience points
|
|
user_id = message.author.id
|
|
current_time = datetime.now()
|
|
|
|
if user_id not in user_cooldowns or (current_time - user_cooldowns[user_id]).total_seconds() >= CHAT_COOLDOWN:
|
|
user_exp_points[user_id] = user_exp_points.get(user_id, 0) + CHAT_EXP_POINTS
|
|
user_cooldowns[user_id] = current_time
|
|
print(f"Added {CHAT_EXP_POINTS} exp points to {message.author.name}. Total: {user_exp_points[user_id]}")
|
|
|
|
await bot.process_commands(message)
|
|
|
|
@bot.event
|
|
async def on_voice_state_update(member, before, after):
|
|
if member.bot:
|
|
return
|
|
|
|
# User joined a voice channel
|
|
if before.channel is None and after.channel is not None:
|
|
voice_time[member.id] = datetime.now()
|
|
active_voice_users.add(member.id)
|
|
print(f"{member.name} joined voice channel {after.channel.name}")
|
|
|
|
# User left a voice channel
|
|
elif before.channel is not None and after.channel is None:
|
|
if member.id in active_voice_users:
|
|
active_voice_users.remove(member.id)
|
|
if member.id in voice_time:
|
|
time_spent = datetime.now() - voice_time[member.id]
|
|
minutes = int(time_spent.total_seconds() / 60)
|
|
exp_points = minutes * VOICE_EXP_POINTS_PER_MINUTE
|
|
user_exp_points[member.id] = user_exp_points.get(member.id, 0) + exp_points
|
|
print(f"{member.name} spent {minutes} minutes in voice. Added {exp_points} exp points. Total: {user_exp_points[member.id]}")
|
|
del voice_time[member.id]
|
|
|
|
@tasks.loop(minutes=1)
|
|
async def update_voice_exp():
|
|
current_time = datetime.now()
|
|
for user_id in list(active_voice_users):
|
|
if user_id in voice_time:
|
|
time_spent = current_time - voice_time[user_id]
|
|
if time_spent.total_seconds() >= 60:
|
|
user_exp_points[user_id] = user_exp_points.get(user_id, 0) + VOICE_EXP_POINTS_PER_MINUTE
|
|
voice_time[user_id] = current_time
|
|
print(f"Added {VOICE_EXP_POINTS_PER_MINUTE} exp points to user {user_id} for voice time")
|
|
|
|
@bot.command(name='exp')
|
|
async def show_exp(ctx):
|
|
user_id = ctx.author.id
|
|
exp = user_exp_points.get(user_id, 0)
|
|
await ctx.send(f"{ctx.author.mention} has {exp} experience points!")
|
|
|
|
print(f"Token: {repr(os.getenv('BOT_TOKEN'))}")
|
|
# Run the bot
|
|
bot.run(os.getenv('BOT_TOKEN'))
|