commit ce5e4865559ce4e03387f1e9b1b9876233e356fe Author: Tobias Leuschner Date: Fri Feb 20 15:32:49 2026 +0100 Füge Bot-Implementierung und Umgebungsvariablen hinzu diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..24eb2b4 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +DISCORD_TOKEN=dein_bot_token_hier diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..84fcd7c --- /dev/null +++ b/bot.py @@ -0,0 +1,132 @@ +import discord +from discord import app_commands +from discord.ext import commands +import json +import os +from dotenv import load_dotenv + +load_dotenv() +TOKEN = os.getenv("DISCORD_TOKEN") +DATA_FILE = "data.json" + + +def load_data() -> dict: + if os.path.exists(DATA_FILE): + with open(DATA_FILE, "r", encoding="utf-8") as f: + return json.load(f) + return {} + + +def save_data(data: dict): + with open(DATA_FILE, "w", encoding="utf-8") as f: + json.dump(data, f, indent=2, ensure_ascii=False) + + +def get_mute_count(data: dict, guild_id: int, user_id: int) -> int: + return data.get(str(guild_id), {}).get(str(user_id), 0) + + +def increment_mute(data: dict, guild_id: int, user_id: int): + gid = str(guild_id) + uid = str(user_id) + if gid not in data: + data[gid] = {} + data[gid][uid] = data[gid].get(uid, 0) + 1 + + +intents = discord.Intents.default() +intents.voice_states = True +intents.members = True + +bot = commands.Bot(command_prefix="!", intents=intents) +mute_data = load_data() + + +@bot.event +async def on_ready(): + print(f"Bot gestartet als {bot.user} (ID: {bot.user.id})") + try: + synced = await bot.tree.sync() + print(f"{len(synced)} Slash-Commands synchronisiert.") + except Exception as e: + print(f"Fehler beim Sync: {e}") + + +@bot.event +async def on_voice_state_update( + member: discord.Member, + before: discord.VoiceState, + after: discord.VoiceState, +): + # Bots ignorieren + if member.bot: + return + + guild = member.guild + + # AFK-Channel ausschließen: Ereignisse ignorieren, wenn Nutzer im AFK-Channel ist + afk_channel = guild.afk_channel + if after.channel is not None and afk_channel is not None and after.channel.id == afk_channel.id: + return + if before.channel is not None and afk_channel is not None and before.channel.id == afk_channel.id: + return + + # Erkennen: Nutzer hat sich gerade selbst gemutet (war vorher nicht gemutet) + just_muted = (not before.self_mute) and after.self_mute + + if just_muted: + increment_mute(mute_data, guild.id, member.id) + save_data(mute_data) + print( + f"{member.display_name} hat sich gemutet " + f"(Gesamt: {get_mute_count(mute_data, guild.id, member.id)}x) " + f"[Server: {guild.name}]" + ) + + +@bot.tree.command(name="mutescore", description="Zeigt das Mute-Leaderboard des Servers.") +@app_commands.describe(limit="Wie viele Plätze anzeigen? (Standard: 10)") +async def mutescore(interaction: discord.Interaction, limit: int = 10): + limit = max(1, min(limit, 25)) + guild = interaction.guild + guild_data: dict = mute_data.get(str(guild.id), {}) + + if not guild_data: + await interaction.response.send_message( + "Noch keine Mutes aufgezeichnet.", ephemeral=True + ) + return + + sorted_entries = sorted(guild_data.items(), key=lambda x: x[1], reverse=True) + top = sorted_entries[:limit] + + embed = discord.Embed( + title="Mute-Leaderboard", + description="Wer mutet sich am häufigsten?", + color=discord.Color.blurple(), + ) + + medals = {1: "🥇", 2: "🥈", 3: "🥉"} + lines = [] + + for rank, (uid, count) in enumerate(top, start=1): + member = guild.get_member(int(uid)) + name = member.display_name if member else f"Unbekannt ({uid})" + medal = medals.get(rank, f"**#{rank}**") + lines.append(f"{medal} {name} — **{count}x** gemutet") + + embed.description = "\n".join(lines) + embed.set_footer(text=f"Top {len(top)} von {len(sorted_entries)} Nutzern") + + await interaction.response.send_message(embed=embed) + + +@bot.tree.command(name="mymutes", description="Zeigt deine eigene Mute-Anzahl.") +async def mymutes(interaction: discord.Interaction): + count = get_mute_count(mute_data, interaction.guild.id, interaction.user.id) + await interaction.response.send_message( + f"Du hast dich bisher **{count}x** gemutet.", ephemeral=True + ) + + +bot.run(TOKEN) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..70ad9a2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +discord.py>=2.3.0 +python-dotenv>=1.0.0