modified: bot.py

This commit is contained in:
SimolZimol
2024-09-16 18:39:05 +02:00
parent 17d5d1bb5a
commit 9e6cfc6ade

165
bot.py
View File

@@ -114,7 +114,7 @@ logger.addHandler(file_handler)
#to do:
# permissions system, Filter, mysql for user data, fix vision, embeds, info cmd (Server Info, user info), logs, points redo, ticket system, levels, mc ranks integration, add image gen, reaction system, dm system, better ready, resource management, bot action (aka playing)
# mysql = userid / permission / points / ban / askmultus-int / Filter-int / rank / chat-history
# mysql = userid / permission / points / ban / askmultus-int / Filter-int / rank / chat-history / guild_id
# 10 filter = acc under review = nicht ok = ban add timestamp = 2 bans = unendlicher ban
#perms || 10 = Owner || 8 = Admin || 5 = Mod
@@ -149,7 +149,8 @@ db_cursor = db_connection.cursor()
# SQL-Befehl für die Erstellung der Tabelle, falls sie noch nicht existiert
create_table_query = """
CREATE TABLE IF NOT EXISTS user_data (
user_id BIGINT PRIMARY KEY,
user_id BIGINT,
guild_id BIGINT,
permission INT,
points INT,
ban INT,
@@ -158,19 +159,20 @@ CREATE TABLE IF NOT EXISTS user_data (
rank INT,
chat_history JSON,
xp INT,
level INT
level INT,
PRIMARY KEY (user_id, guild_id)
);
"""
db_cursor.execute(create_table_query)
db_connection.commit()
def insert_user_data(user_id, permission, points, ban, askmultus, filter_value, chat_history):
def insert_user_data(user_id, guild_id, permission, points, ban, askmultus, filter_value, chat_history):
insert_query = """
INSERT INTO user_data (user_id, permission, points, ban, askmultus, filter_value, rank, chat_history, xp, level)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
INSERT INTO user_data (user_id, guild_id, permission, points, ban, askmultus, filter_value, rank, chat_history, xp, level)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
serialized_chat_history = json.dumps(chat_history)
data = (user_id, permission, points, ban, askmultus, filter_value, 0, serialized_chat_history, 0, 1) # Initialisiere XP auf 0 und Level auf 1
data = (user_id, guild_id, permission, points, ban, askmultus, filter_value, 0, serialized_chat_history, 0, 1) # Initialisiere XP auf 0 und Level auf 1
try:
db_cursor.execute(insert_query, data)
db_connection.commit()
@@ -180,18 +182,17 @@ def insert_user_data(user_id, permission, points, ban, askmultus, filter_value,
db_connection.rollback()
def update_user_data(user_id, field, value):
def update_user_data(user_id, guild_id, field, value):
global db_connection, db_cursor # global-Deklaration muss vor dem Zugriff erfolgen
try:
update_query = f"UPDATE user_data SET {field} = %s WHERE user_id = %s"
update_query = f"UPDATE user_data SET {field} = %s WHERE user_id = %s AND guild_id = %s"
# Überprüfen, ob das Feld 'chat_history' aktualisiert wird
if field == 'chat_history':
# Serialize the chat history list to a JSON string
serialized_chat_history = json.dumps(value)
db_cursor.execute(update_query, (serialized_chat_history, user_id))
db_cursor.execute(update_query, (serialized_chat_history, user_id, guild_id))
else:
db_cursor.execute(update_query, (value, user_id))
db_cursor.execute(update_query, (value, user_id, guild_id))
db_connection.commit()
@@ -206,7 +207,7 @@ def update_user_data(user_id, field, value):
db_cursor = db_connection.cursor()
# Wiederhole die Abfrage nach dem erneuten Verbinden
update_user_data(user_id, field, value)
update_user_data(user_id, guild_id, field, value)
def connect_to_database():
@@ -221,11 +222,11 @@ def connect_to_database():
def close_database_connection(connection):
connection.close()
def load_user_data_from_mysql(user_id):
def load_user_data_from_mysql(user_id, guild_id):
connection = connect_to_database()
cursor = connection.cursor()
select_query = "SELECT * FROM user_data WHERE user_id = %s"
cursor.execute(select_query, (user_id,))
select_query = "SELECT * FROM user_data WHERE user_id = %s AND guild_id = %s"
cursor.execute(select_query, (user_id, guild_id))
result = cursor.fetchone()
cursor.close()
@@ -235,21 +236,23 @@ def load_user_data_from_mysql(user_id):
# Wenn das Level und die XP nicht vorhanden sind, initialisieren
user_data = {
"user_id": result[0],
"permission": result[1],
"points": result[2],
"ban": result[3],
"askmultus": result[4],
"filter_value": result[5],
"rank": result[6],
"chat_history": json.loads(result[7]) if result[7] else [],
"asknotes_history": json.loads(result[8]) if result[8] else [],
"xp": result[9],
"level": result[10]
"guild_id": result[1],
"permission": result[2],
"points": result[3],
"ban": result[4],
"askmultus": result[5],
"filter_value": result[6],
"rank": result[7],
"chat_history": json.loads(result[8]) if result[8] else [],
"asknotes_history": json.loads(result[9]) if result[9] else [],
"xp": result[10],
"level": result[11]
}
else:
# Falls keine Benutzerdaten gefunden werden, initialisiere sie neu
user_data = {
"user_id": user_id,
"guild_id": guild_id,
"permission": 0, # Standardberechtigung
"points": 0, # Standardpunkte
"ban": 0, # Standardbannstatus
@@ -259,12 +262,12 @@ def load_user_data_from_mysql(user_id):
"chat_history": [], # Leerer Chatverlauf
"asknotes_history": [], # Leerer Chatverlauf
"xp": 0, # Standard-XP
"level": 1 # Standardlevel
"level": 1 # Standardlevel
}
# Fügen Sie die neuen Benutzerdaten zur Datenbank hinzu
insert_user_data(
user_data["user_id"],
user_data["guild_id"],
user_data["permission"],
user_data["points"],
user_data["ban"],
@@ -274,7 +277,6 @@ def load_user_data_from_mysql(user_id):
user_data["asknotes_history"],
user_data["xp"],
user_data["level"]
)
return user_data
@@ -283,28 +285,28 @@ def load_user_data_from_mysql(user_id):
cached_user_data = {}
pending_deletion = {}
async def cache_user_data(user_id, data):
cached_user_data[user_id] = data
async def cache_user_data(user_id, guild_id, data):
cached_user_data[(user_id, guild_id)] = data
# Setze die Daten nach 30 Sekunden auf die Löschliste
if user_id not in pending_deletion:
pending_deletion[user_id] = asyncio.get_event_loop().call_later(30, lambda: remove_user_data_from_cache(user_id))
if (user_id, guild_id) not in pending_deletion:
pending_deletion[(user_id, guild_id)] = asyncio.get_event_loop().call_later(30, lambda: remove_user_data_from_cache(user_id, guild_id))
def remove_user_data_from_cache(user_id):
def remove_user_data_from_cache(user_id, guild_id):
# Entferne den Benutzer aus dem Cache und der Löschliste
if user_id in cached_user_data:
del cached_user_data[user_id]
if user_id in pending_deletion:
pending_deletion[user_id].cancel()
del pending_deletion[user_id]
if (user_id, guild_id) in cached_user_data:
del cached_user_data[(user_id, guild_id)]
if (user_id, guild_id) in pending_deletion:
pending_deletion[(user_id, guild_id)].cancel()
del pending_deletion[(user_id, guild_id)]
def load_user_data(user_id):
if user_id in cached_user_data:
return cached_user_data[user_id]
def load_user_data(user_id, guild_id):
if (user_id, guild_id) in cached_user_data:
return cached_user_data[(user_id, guild_id)]
# Daten aus der Datenbank laden oder einfügen
user_data = load_user_data_from_mysql(user_id)
asyncio.ensure_future(cache_user_data(user_id, user_data))
user_data = load_user_data_from_mysql(user_id, guild_id)
asyncio.ensure_future(cache_user_data(user_id, guild_id, user_data))
return user_data
@@ -368,7 +370,8 @@ class Giveaway:
@client.hybrid_command()
async def startgiveaway(ctx, platform: str, prize: str, num_winners: int, title: str, subtitle: str, duration: str):
"""Creates a giveaway. Only available for mods and higher."""
user_data = load_user_data(ctx.author.id)
guild_id = ctx.guild.id
user_data = load_user_data(ctx.author.id, guild_id)
if user_data["permission"] < 5:
await ctx.send("You do not have permission to create a giveaway.")
return
@@ -418,7 +421,7 @@ async def check_giveaway(giveaway_id):
# Jeden Gewinner benachrichtigen und zur Webseite schicken
for winner in winners:
user_data = load_user_data(winner.id)
user_data = load_user_data(winner.id, giveaway.ctx.guild.id)
# Gewinner in der Datenbank speichern (winner_dc_id)
update_winner_in_db(giveaway.prize_uuid, winner.id)
# Nachricht an den Gewinner senden
@@ -484,10 +487,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, xp_gained):
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)
user_data = load_user_data(user_id, guild_id)
# Füge die gewonnenen XP hinzu
user_data["xp"] += xp_gained
@@ -506,16 +509,17 @@ async def add_xp_to_user(user_id, xp_gained):
xp_needed = calculate_xp_needed_for_level(user_data["level"])
# Speichere die aktualisierten Benutzerdaten in der Datenbank
update_user_data(user_id, "xp", user_data["xp"])
update_user_data(user_id, "level", user_data["level"])
update_user_data(user_id, guild_id, "xp", user_data["xp"])
update_user_data(user_id, guild_id, "level", user_data["level"])
@client.hybrid_command()
async def level(ctx):
"""Zeigt den aktuellen Level und XP des Benutzers an."""
user_id = ctx.author.id
guild_id = ctx.guild.id
# Lade die Benutzerdaten (XP und Level) aus der Datenbank
user_data = load_user_data(user_id)
user_data = load_user_data(user_id, guild_id)
# Berechne die für das nächste Level benötigten XP
current_level = user_data["level"]
@@ -534,14 +538,15 @@ async def level(ctx):
@client.hybrid_command()
async def leaderboard(ctx):
"""Zeigt die besten Benutzer im XP-Leaderboard an."""
guild_id = ctx.guild.id
connection = connect_to_database()
cursor = connection.cursor()
# Abfrage, um die Benutzer basierend auf der XP zu sortieren
select_query = """
SELECT user_id, xp, level FROM user_data ORDER BY level DESC, xp DESC LIMIT 10
SELECT user_id, xp, level FROM user_data WHERE guild_id = %s ORDER BY level DESC, xp DESC LIMIT 10
"""
cursor.execute(select_query)
cursor.execute(select_query, (guild_id,))
result = cursor.fetchall()
# Liste, um die Benutzer und ihre XP zu speichern
@@ -581,8 +586,9 @@ async def on_message(message):
return # Ignoriere Nachrichten von Bots
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, xp_gained)
await add_xp_to_user(user_id, guild_id, xp_gained)
# Weiterleiten der Nachricht an andere Event-Handler
await client.process_commands(message)
@@ -627,8 +633,9 @@ async def on_command(ctx):
async def points(ctx):
"""Shows how many points you have."""
user_id = ctx.author.id
guild_id = ctx.guild.id
# Lade Benutzerdaten aus der MySQL-Datenbank
user_data = load_user_data(user_id)
user_data = load_user_data(user_id, guild_id)
points = user_data["points"]
@@ -643,9 +650,10 @@ async def points(ctx):
async def permissionlevel(ctx):
"""Displays the authorisation level and rank of the user."""
user_id = ctx.author.id
guild_id = ctx.guild.id
# Load user data from the MySQL database
user_data = load_user_data(user_id)
user_data = load_user_data(user_id, guild_id)
permission_level = user_data["permission"]
rank = ""
@@ -668,18 +676,19 @@ async def permissionlevel(ctx):
@client.hybrid_command()
async def addpoints(ctx, user: discord.User, amount: int):
"""Adds a certain number of points to a user."""
user_perms = load_user_data(ctx.author.id)
user_perms = load_user_data(ctx.author.id, ctx.guild.id)
if 5 <= user_perms["permission"]:
user_id = user.id
guild_id = ctx.guild.id
# Lade Benutzerdaten aus der MySQL-Datenbank
user_data = load_user_data(user_id)
user_data = load_user_data(user_id, guild_id)
# Füge die Punkte hinzu
user_data["points"] += amount
# Speichere die aktualisierten Benutzerdaten in der MySQL-Datenbank
update_user_data(user_data["user_id"], "points", user_data["points"])
update_user_data(user_data["user_id"], guild_id, "points", user_data["points"])
embed = discord.Embed(
title="Points Added",
@@ -693,18 +702,19 @@ async def addpoints(ctx, user: discord.User, amount: int):
@client.hybrid_command()
async def resetpoints(ctx, user: discord.User):
"""Resets a user's points to 0."""
user_perms = load_user_data(ctx.author.id)
user_perms = load_user_data(ctx.author.id, ctx.guild.id)
if 5 <= user_perms["permission"]:
user_id = user.id
guild_id = ctx.guild.id
# Lade Benutzerdaten aus der MySQL-Datenbank
user_data = load_user_data(user_id)
user_data = load_user_data(user_id, guild_id)
# Setze die Punkte auf 0 zurück
user_data["points"] = 0
# Speichere die aktualisierten Benutzerdaten in der MySQL-Datenbank
update_user_data(user_data["user_id"], "points", user_data["points"])
update_user_data(user_data["user_id"], guild_id, "points", user_data["points"])
embed = discord.Embed(
title="Points Reset",
@@ -717,7 +727,7 @@ async def resetpoints(ctx, user: discord.User):
@client.hybrid_command()
async def shutdown_(ctx):
user_perms = load_user_data(ctx.author.id)
user_perms = load_user_data(ctx.author.id, ctx.guild.id)
if 8 <= user_perms["permission"]:
await ctx.send("Shutting down the bot...")
await client.logout()
@@ -728,7 +738,7 @@ async def shutdown_(ctx):
@client.hybrid_command()
async def owner_command(ctx):
try:
user_perms = load_user_data(ctx.author.id)
user_perms = load_user_data(ctx.author.id, ctx.guild.id)
if 10 <= user_perms["permission"]:
await client.tree.sync()
await ctx.send("reloaded !")
@@ -745,15 +755,16 @@ async def askmultus(ctx, *, prompt: str):
return
user_id = ctx.author.id
guild_id = ctx.guild.id
# Lade Benutzerdaten aus der MySQL-Datenbank
user_data = load_user_data(user_id)
user_data = load_user_data(user_id, guild_id)
if user_data["points"] >= 5:
user_data["points"] -= 5
# Speichere die aktualisierten Benutzerdaten in der MySQL-Datenbank
update_user_data(user_data["user_id"], "points", user_data["points"])
update_user_data(user_data["user_id"], guild_id, "points", user_data["points"])
# Define the full data and user history field for askmultus
introduction = read_introduction()
@@ -782,7 +793,8 @@ async def process_ai_queue():
if not askmultus_queue.empty():
ctx, user_id, user_name, prompt, channel_id, full_data, user_history_field, model = await askmultus_queue.get()
user_data = load_user_data(user_id)
guild_id = ctx.guild.id
user_data = load_user_data(user_id, guild_id)
try:
user_history = user_data.get(user_history_field, [])
@@ -826,7 +838,7 @@ async def process_ai_queue():
user_history.append({"role": "assistant", "content": assistant_message})
# Update the relevant user history field
update_user_data(user_data["user_id"], user_history_field, json.dumps(user_history))
update_user_data(user_data["user_id"], guild_id, user_history_field, json.dumps(user_history))
except Exception as e:
logger.error(f"Processing errors: {e}")
@@ -906,7 +918,8 @@ async def addbackgrounddata(ctx, *, data: str):
@client.hybrid_command()
async def summarize(ctx, number: int):
"""Summarizes the last x messages in the chat."""
user_perms = load_user_data(ctx.author.id)
guild_id = ctx.guild.id
user_perms = load_user_data(ctx.author.id, guild_id)
if 5 < user_perms["permission"]:
try:
# Fetch the last 10 messages in the channel
@@ -968,8 +981,9 @@ async def leave(ctx):
@client.hybrid_command()
async def toggle_feature(ctx, feature: str, state: str):
"""Allows admin to enable or disable features."""
guild_id = ctx.guild.id
user_id = ctx.author.id
user_data = load_user_data(user_id)
user_data = load_user_data(user_id, guild_id)
user_perms = user_data["permission"]
if user_perms < 8: # Nur Admins (permission level >= 8) können Funktionen aktivieren/deaktivieren
@@ -1010,7 +1024,8 @@ async def addnotes(ctx, type: str, *, source: str):
await ctx.defer() # Signalisiert, dass die Bearbeitung des Befehls begonnen hat
user_id = ctx.author.id
user_cache_dir = os.path.join(CACHE_DIR, str(user_id))
guild_id = ctx.guild.id
user_cache_dir = os.path.join(CACHE_DIR, f"{str(guild_id)}_{str(user_id)}")
if not os.path.exists(user_cache_dir):
os.makedirs(user_cache_dir)
@@ -1057,7 +1072,8 @@ async def asknotes(ctx, *, question: str):
await ctx.defer()
user_id = ctx.author.id
user_cache_dir = os.path.join(CACHE_DIR, str(user_id))
guild_id = ctx.guild.id
user_cache_dir = os.path.join(CACHE_DIR, f"{str(guild_id)}_{str(user_id)}")
note_file = os.path.join(user_cache_dir, "notes.txt")
asknotesintroduction = read_askintroduction()
@@ -1086,7 +1102,8 @@ async def asknotes(ctx, *, question: str):
async def delnotes(ctx):
"""Deletes all saved notes and the asknotes history for the user."""
user_id = ctx.author.id
user_cache_dir = os.path.join(CACHE_DIR, str(user_id))
guild_id = ctx.guild.id
user_cache_dir = os.path.join(CACHE_DIR, f"{str(guild_id)}_{str(user_id)}")
if os.path.exists(user_cache_dir):
# Lösche die gespeicherten Notizen im Cache-Ordner
@@ -1094,7 +1111,7 @@ async def delnotes(ctx):
# Setze die asknotes-Historie in der Datenbank zurück
try:
update_user_data(user_id, "asknotes_history", None)
update_user_data(user_id, guild_id, "asknotes_history", None)
await ctx.send(f"All notes and asknotes history deleted for user {ctx.author.name}.")
except Exception as e:
await ctx.send(f"Error deleting asknotes history: {e}")