mirror of
https://gitlab.com/pancakes1234/wdiscordbotserver.git
synced 2025-06-16 07:14:21 -06:00
- Reorganizes application commands across cogs into logical groups and subgroups for improved usability and maintainability. - Introduces a local Hugging Face Transformer model (Gemma 2B IT) to provide context-aware emoji suggestions, enhancing bot interaction. - Converts remaining hybrid commands to pure application commands. - Updates global command disable check registration and includes minor UI and error handling improvements.
162 lines
5.8 KiB
Python
162 lines
5.8 KiB
Python
import discord
|
||
from discord.ext import commands
|
||
from discord import app_commands
|
||
import os
|
||
import json
|
||
|
||
# Path to the JSON config file
|
||
CONFIG_FILE = "/home/server/serverconfig.json"
|
||
|
||
def load_config() -> dict:
|
||
"""Load the server configuration from file.
|
||
If the file does not exist or is invalid, create a new empty configuration."""
|
||
if not os.path.exists(CONFIG_FILE):
|
||
with open(CONFIG_FILE, "w") as f:
|
||
json.dump({}, f)
|
||
return {}
|
||
try:
|
||
with open(CONFIG_FILE, "r") as f:
|
||
return json.load(f)
|
||
except json.JSONDecodeError:
|
||
return {}
|
||
|
||
def save_config(data: dict) -> None:
|
||
"""Save the configuration JSON to file."""
|
||
with open(CONFIG_FILE, "w") as f:
|
||
json.dump(data, f, indent=4)
|
||
|
||
async def global_disabled_check(interaction: discord.Interaction) -> bool:
|
||
"""
|
||
Global check for all app (slash) commands.
|
||
If the command (except for serverconfig itself) is marked as disabled in this server’s config,
|
||
send an ephemeral message and prevent execution.
|
||
"""
|
||
# If interaction comes from a DM, allow it.
|
||
if interaction.guild is None:
|
||
return True
|
||
|
||
# Always allow the serverconfig command so admins can change settings.
|
||
if interaction.command and interaction.command.name == "serverconfig":
|
||
return True
|
||
|
||
config = load_config()
|
||
guild_id = str(interaction.guild.id)
|
||
disabled_commands = config.get(guild_id, [])
|
||
|
||
if interaction.command and interaction.command.name in disabled_commands:
|
||
if not interaction.response.is_done():
|
||
await interaction.response.send_message(
|
||
"This command has been disabled by server admins.", ephemeral=True
|
||
)
|
||
# Raising a CheckFailure prevents the command from running.
|
||
raise app_commands.CheckFailure("Command disabled.")
|
||
return True
|
||
|
||
class ServerConfigCog(commands.Cog):
|
||
def __init__(self, bot: commands.Bot):
|
||
self.bot = bot
|
||
|
||
@app_commands.command(
|
||
name="serverconfig",
|
||
description="Enable or disable a command in this server."
|
||
)
|
||
@app_commands.describe(
|
||
command="The name of the command to configure",
|
||
enabled="Type 'yes' to enable or 'no' to disable."
|
||
)
|
||
async def serverconfig(
|
||
self,
|
||
interaction: discord.Interaction,
|
||
command: str,
|
||
enabled: str
|
||
):
|
||
# Check if the user has admin permissions.
|
||
if not interaction.user.guild_permissions.administrator:
|
||
await interaction.response.send_message(
|
||
"You do not have permission to use this command.",
|
||
ephemeral=True
|
||
)
|
||
return
|
||
|
||
# Normalize the enabled flag.
|
||
enabled_flag = enabled.lower()
|
||
if enabled_flag not in ["yes", "no"]:
|
||
await interaction.response.send_message(
|
||
"Invalid 'enabled' option. Please use 'yes' or 'no'.",
|
||
ephemeral=True
|
||
)
|
||
return
|
||
|
||
# Verify that the provided command exists.
|
||
found = False
|
||
# Check the classic text commands.
|
||
for cmd in self.bot.commands:
|
||
if cmd.name == command:
|
||
found = True
|
||
break
|
||
# Also check application (slash) commands from the tree.
|
||
if not found:
|
||
for cmd in self.bot.tree.get_commands():
|
||
if cmd.name == command:
|
||
found = True
|
||
break
|
||
if not found:
|
||
await interaction.response.send_message(
|
||
f"The command '{command}' was not found.",
|
||
ephemeral=True
|
||
)
|
||
return
|
||
|
||
# Load the configuration.
|
||
config = load_config()
|
||
guild_id = str(interaction.guild.id)
|
||
if guild_id not in config:
|
||
config[guild_id] = []
|
||
|
||
if enabled_flag == "no":
|
||
# Add the command to the disabled list if not already present.
|
||
if command not in config[guild_id]:
|
||
config[guild_id].append(command)
|
||
save_config(config)
|
||
await interaction.response.send_message(
|
||
f"Command '{command}' has been **disabled** in this server.",
|
||
ephemeral=True
|
||
)
|
||
else: # enabled_flag == "yes"
|
||
# Remove the command from the disabled list if present.
|
||
if command in config[guild_id]:
|
||
config[guild_id].remove(command)
|
||
save_config(config)
|
||
await interaction.response.send_message(
|
||
f"Command '{command}' has been **enabled** in this server.",
|
||
ephemeral=True
|
||
)
|
||
|
||
@serverconfig.autocomplete("command")
|
||
async def command_autocomplete(
|
||
self, interaction: discord.Interaction, current: str
|
||
) -> list[app_commands.Choice[str]]:
|
||
"""
|
||
Autocomplete for the 'command' parameter.
|
||
It searches both classic and slash commands for matches.
|
||
"""
|
||
choices = set()
|
||
# Get names of text commands.
|
||
for cmd in self.bot.commands:
|
||
choices.add(cmd.name)
|
||
# Get names of app commands.
|
||
for cmd in self.bot.tree.get_commands():
|
||
choices.add(cmd.name)
|
||
# Filter and send at most 25 matching choices.
|
||
filtered = [
|
||
app_commands.Choice(name=cmd, value=cmd)
|
||
for cmd in choices
|
||
if current.lower() in cmd.lower()
|
||
]
|
||
return filtered[:25]
|
||
|
||
async def setup(bot: commands.Bot):
|
||
# Register the global check – it will run for every application (slash) command.
|
||
bot.tree.interaction_check = global_disabled_check
|
||
await bot.add_cog(ServerConfigCog(bot))
|