From 4d9214e3783a11a1d7dde5725b07fb436a805356 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 21 Jun 2024 22:14:26 -0400 Subject: [PATCH] FEAT: Added XP System, need to test and adjust it REF: Adjusted the Twitch Module to be on a 5 minute cooldown DOC: Adjusted related code for the new XP system in db and config --- config.py | 1 + modules/data/db.py | 7 +++ modules/social/twitch_module.py | 2 +- modules/user/xp_module.py | 83 +++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 modules/user/xp_module.py diff --git a/config.py b/config.py index 2970904..a613530 100644 --- a/config.py +++ b/config.py @@ -19,6 +19,7 @@ YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY") ENABLED_MODULES = [ "modules.media.spotify_module", "modules.user.birthday_module", + "modules.user.xp_module", "modules.money.currency_module", "modules.social.twitch_module", "modules.social.youtube_module", diff --git a/modules/data/db.py b/modules/data/db.py index 5c362bb..3d405b4 100644 --- a/modules/data/db.py +++ b/modules/data/db.py @@ -41,6 +41,13 @@ def initialize_db(): last_video_id TEXT ) ''') + cursor.execute(''' + CREATE TABLE IF NOT EXISTS user_xp ( + user_id INTEGER PRIMARY KEY, + xp INTEGER, + level INTEGER + ) + ''') conn.commit() conn.close() diff --git a/modules/social/twitch_module.py b/modules/social/twitch_module.py index 64bf3e5..23650be 100644 --- a/modules/social/twitch_module.py +++ b/modules/social/twitch_module.py @@ -75,7 +75,7 @@ class TwitchModule: logger.error(f"Error checking live status for {twitch_name}: {e}", exc_info=True) conn.close() - await asyncio.sleep(120) # Check every 2 minutes for testing purposes + await asyncio.sleep(300) # Check every 5 minutes def add_commands(self): @app_commands.command( diff --git a/modules/user/xp_module.py b/modules/user/xp_module.py new file mode 100644 index 0000000..780aa84 --- /dev/null +++ b/modules/user/xp_module.py @@ -0,0 +1,83 @@ +import discord +from discord import app_commands +import logging +from modules.data.db import get_connection +from datetime import datetime, timedelta + +logger = logging.getLogger(__name__) + + +class XPModule: + def __init__(self, bot): + self.bot = bot + self.cooldown = {} # Dictionary to store cooldowns + self.add_commands() + + async def on_message(self, message): + if message.author.bot: + return + + user_id = message.author.id + now = datetime.now() + + if user_id in self.cooldown: + if now < self.cooldown[user_id]: + return # User is on cooldown + + self.give_xp(user_id, 10) # Give 10 XP for a message + self.cooldown[user_id] = now + timedelta(seconds=60) # 1 minute cooldown + + def give_xp(self, user_id, xp): + conn = get_connection() + c = conn.cursor() + c.execute('SELECT xp, level FROM user_xp WHERE user_id = ?', (user_id,)) + row = c.fetchone() + + if row: + current_xp, current_level = row + new_xp = current_xp + xp + new_level = current_level + + # Level up logic + if new_xp >= self.xp_for_next_level(current_level): + new_level += 1 + new_xp = new_xp - self.xp_for_next_level(current_level) + logger.info(f"User {user_id} leveled up to {new_level}") + + c.execute('UPDATE user_xp SET xp = ?, level = ? WHERE user_id = ?', (new_xp, new_level, user_id)) + else: + c.execute('INSERT INTO user_xp (user_id, xp, level) VALUES (?, ?, ?)', (user_id, xp, 1)) + + conn.commit() + conn.close() + + def xp_for_next_level(self, level): + return 100 * level # Example leveling curve + + def add_commands(self): + @app_commands.command(name='xp', description='Check your XP and level') + async def check_xp(interaction: discord.Interaction): + user_id = interaction.user.id + conn = get_connection() + c = conn.cursor() + c.execute('SELECT xp, level FROM user_xp WHERE user_id = ?', (user_id,)) + row = c.fetchone() + conn.close() + + if row: + xp, level = row + await interaction.response.send_message(f"You have {xp} XP and are level {level}.") + else: + await interaction.response.send_message("You have no XP yet.") + + self.bot.tree.add_command(check_xp) + + +async def setup(bot): + xp_module = XPModule(bot) + + @bot.event + async def on_message(message): + if not message.author.bot: # Ensure the bot doesn't earn XP + await xp_module.on_message(message) + await bot.process_commands(message) # Process commands after the XP check \ No newline at end of file