diff --git a/bot.py b/bot.py index e9ac9ae..c52f775 100644 --- a/bot.py +++ b/bot.py @@ -204,6 +204,47 @@ def close_database_connection(connection): if connection and connection.is_connected(): connection.close() +def create_user_data_with_member(user_id, guild_id, member=None): + """Erstellt neue User-Daten mit korrekten Informationen vom Member-Objekt""" + nickname = member.display_name if member else "" + profile_picture = str(member.display_avatar.url) if member and member.display_avatar else None + join_date = member.joined_at.date() if member and member.joined_at else None + + user_data = { + "user_id": user_id, + "guild_id": guild_id, + "permission": 0, + "points": 0, + "ban": 0, + "askmultus": 0, + "filter_value": 0, + "rank": 0, + "chat_history": [], + "asknotes_history": [], + "xp": 0, + "level": 1, + "nickname": nickname + } + + insert_user_data( + user_data["user_id"], + user_data["guild_id"], + user_data["permission"], + user_data["points"], + user_data["ban"], + user_data["askmultus"], + user_data["filter_value"], + user_data["chat_history"], + user_data["xp"], + user_data["level"], + nickname, + profile_picture, + join_date + ) + + logger.info(f"Created new user data for {nickname} (ID: {user_id}) with join_date: {join_date}") + return user_data + def load_user_data_from_mysql(user_id, guild_id): connection = None cursor = None @@ -303,14 +344,18 @@ def remove_user_data_from_cache(user_id, guild_id): pending_deletion[(user_id, guild_id)].cancel() del pending_deletion[(user_id, guild_id)] -def load_user_data(user_id, guild_id): +def load_user_data(user_id, guild_id, member=None): if (user_id, guild_id) in cached_user_data: return cached_user_data[(user_id, guild_id)] # Daten aus der Datenbank laden oder neu anlegen user_data = load_user_data_from_mysql(user_id, guild_id) - asyncio.ensure_future(cache_user_data(user_id, guild_id, user_data)) + # Wenn keine User-Daten existieren, erstelle neue mit Member-Informationen + if not user_data or user_data.get("user_id") is None: + user_data = create_user_data_with_member(user_id, guild_id, member) + + asyncio.ensure_future(cache_user_data(user_id, guild_id, user_data)) return user_data def get_global_permission(user_id): @@ -831,10 +876,10 @@ def calculate_xp_needed_for_level(level): xp_need = 5 * (int(level) ** 2) + 50 * int(level) + 100 return int(xp_need) -async def add_xp_to_user(user_id, guild_id, xp_gained): - """Fügt einem Benutzer XP hinzu und überprüft, ob er ein Level aufsteigt.""" - # Lade Benutzerdaten (XP, Level, etc.) - user_data = load_user_data(user_id, guild_id) +async def add_xp_to_user(user_id, guild_id, xp_gained, member=None): + """Fügt einem Benutzer XP hinzu und überprüft, ob er ein Level aufsteigt. Aktualisiert auch Benutzerdaten.""" + # Lade Benutzerdaten (XP, Level, etc.) - mit member-Objekt für neue User + user_data = load_user_data(user_id, guild_id, member) # Initialisiere XP, falls es None ist user_data["xp"] = user_data.get("xp", 0) @@ -847,18 +892,49 @@ async def add_xp_to_user(user_id, guild_id, xp_gained): xp_needed = calculate_xp_needed_for_level(level) # Überprüfe, ob der Benutzer aufgestiegen ist + level_up = False while user_data["xp"] >= xp_needed: # Reduziere die überschüssigen XP und erhöhe das Level user_data["xp"] -= xp_needed user_data["level"] += 1 + level_up = True # Berechne die neuen XP-Anforderungen für das nächste Level xp_needed = calculate_xp_needed_for_level(user_data["level"]) - # Speichere die aktualisierten Benutzerdaten in der Datenbank + # Aktualisiere Benutzerdaten wenn member-Objekt verfügbar ist + if member: + try: + # Aktualisiere Nickname + new_nickname = member.display_name + if user_data.get("nickname") != new_nickname: + update_user_data(user_id, guild_id, "nickname", new_nickname) + user_data["nickname"] = new_nickname + + # Aktualisiere Profilbild + new_profile_picture = str(member.display_avatar.url) if member.display_avatar else None + if user_data.get("profile_picture") != new_profile_picture: + update_user_data(user_id, guild_id, "profile_picture", new_profile_picture) + user_data["profile_picture"] = new_profile_picture + + # Aktualisiere Join-Datum - IMMER wenn member.joined_at verfügbar ist + if member.joined_at: + join_date = member.joined_at.date() + # Aktualisiere Join-Datum auch wenn es bereits existiert (für den Fall, dass es falsch war) + update_user_data(user_id, guild_id, "join_date", join_date) + user_data["join_date"] = join_date + + logger.info(f"Updated user data for {member.display_name} (ID: {user_id}) - Nickname: {new_nickname}, Join Date: {join_date if member.joined_at else 'N/A'}") + + except Exception as e: + logger.error(f"Error updating user data during XP gain: {e}") + + # Speichere die aktualisierten XP und Level in der Datenbank update_user_data(user_id, guild_id, "xp", user_data["xp"]) update_user_data(user_id, guild_id, "level", user_data["level"]) + return level_up # Gibt zurück, ob ein Level-Up stattgefunden hat + @client.hybrid_command() async def level(ctx, user: discord.User = None): """Zeigt den aktuellen Level und XP des Benutzers oder einer anderen Person an.""" @@ -942,10 +1018,42 @@ async def on_message(message): if message.author.bot: return # Ignoriere Nachrichten von Bots + # Überprüfe, ob die Nachricht in einem Server gesendet wurde + if message.guild is None: + await client.process_commands(message) + return + user_id = message.author.id guild_id = message.guild.id - xp_gained = random.randint(2, 25) # Zufällige XP zwischen 15 und 25 vergeben - await add_xp_to_user(user_id, guild_id, xp_gained) + member = message.author # Das Member-Objekt für Datenaktualisierung + + # XP-Cooldown überprüfen (60 Sekunden) + cooldown_key = (user_id, guild_id) + current_time = time.time() + + if cooldown_key in xp_cooldowns: + time_since_last_xp = current_time - xp_cooldowns[cooldown_key] + if time_since_last_xp < 60: # 60 Sekunden Cooldown + await client.process_commands(message) + return + + # Cooldown aktualisieren + xp_cooldowns[cooldown_key] = current_time + + xp_gained = random.randint(2, 25) # Zufällige XP zwischen 2 und 25 vergeben + + # XP vergeben und Benutzerdaten aktualisieren + level_up = await add_xp_to_user(user_id, guild_id, xp_gained, member) + + # Optional: Level-Up Benachrichtigung senden + if level_up: + user_data = load_user_data(user_id, guild_id) + new_level = user_data["level"] + try: + await message.channel.send(f"🎉 {member.mention} has reached **Level {new_level}**! Congratulations! 🎉") + except: + # Falls das Senden fehlschlägt, einfach überspringen + pass # Weiterleiten der Nachricht an andere Event-Handler await client.process_commands(message)