feat: Add /reload command and implement dynamic command reloading functionality in KyokoClient.

This commit is contained in:
syntaxbullet
2025-12-05 12:35:37 +01:00
parent 48995204a5
commit 1a5503a3a6
3 changed files with 44 additions and 6 deletions

View File

@@ -0,0 +1,31 @@
import { createCommand } from "@lib/utils";
import { KyokoClient } from "@lib/KyokoClient";
import { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } from "discord.js";
export const reload = createCommand({
data: new SlashCommandBuilder()
.setName("reload")
.setDescription("Reloads all commands")
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
execute: async (interaction) => {
await interaction.deferReply({ ephemeral: true });
try {
await KyokoClient.loadCommands(true);
const embed = new EmbedBuilder()
.setTitle("✅ System Reloaded")
.setDescription(`Successfully reloaded ${KyokoClient.commands.size} commands.`)
.setColor("Green");
await interaction.editReply({ embeds: [embed] });
} catch (error) {
console.error(error);
const embed = new EmbedBuilder()
.setTitle("❌ Reload Failed")
.setDescription("An error occurred while reloading commands. Check console for details.")
.setColor("Red");
await interaction.editReply({ embeds: [embed] });
}
}
});

View File

@@ -13,12 +13,17 @@ class Client extends DiscordClient {
this.commands = new Collection<string, Command>(); this.commands = new Collection<string, Command>();
} }
async loadCommands() { async loadCommands(reload: boolean = false) {
if (reload) {
this.commands.clear();
console.log("♻️ Reloading commands...");
}
const commandsPath = join(import.meta.dir, '../commands'); const commandsPath = join(import.meta.dir, '../commands');
await this.readCommandsRecursively(commandsPath); await this.readCommandsRecursively(commandsPath, reload);
} }
private async readCommandsRecursively(dir: string) { private async readCommandsRecursively(dir: string, reload: boolean = false) {
try { try {
const files = await readdir(dir, { withFileTypes: true }); const files = await readdir(dir, { withFileTypes: true });
@@ -26,14 +31,15 @@ class Client extends DiscordClient {
const filePath = join(dir, file.name); const filePath = join(dir, file.name);
if (file.isDirectory()) { if (file.isDirectory()) {
await this.readCommandsRecursively(filePath); await this.readCommandsRecursively(filePath, reload);
continue; continue;
} }
if (!file.name.endsWith('.ts') && !file.name.endsWith('.js')) continue; if (!file.name.endsWith('.ts') && !file.name.endsWith('.js')) continue;
try { try {
const commandModule = await import(filePath); const importPath = reload ? `${filePath}?t=${Date.now()}` : filePath;
const commandModule = await import(importPath);
const commands = Object.values(commandModule); const commands = Object.values(commandModule);
if (commands.length === 0) { if (commands.length === 0) {
console.warn(`⚠️ No commands found in ${file.name}`); console.warn(`⚠️ No commands found in ${file.name}`);

View File

@@ -3,12 +3,13 @@ import { KyokoClient } from "@lib/KyokoClient";
console.log("🚀 Starting deployment script..."); console.log("🚀 Starting deployment script...");
// Load all commands first // Load all commands first
await KyokoClient.loadCommands(); await KyokoClient.loadCommands(false);
console.log(`📦 Loaded ${KyokoClient.commands.size} commands.`); console.log(`📦 Loaded ${KyokoClient.commands.size} commands.`);
// Deploy // Deploy
await KyokoClient.deployCommands(); await KyokoClient.deployCommands();
console.log("👋 Deployment script finished."); console.log("👋 Deployment script finished.");
process.exit(0); process.exit(0);