Upload 8 files
Browse files- Commands/eval.ts +42 -0
- Commands/help.ts +29 -0
- Commands/mass-dm.ts +125 -0
- Commands/ping.ts +19 -0
- Commands/play.ts +100 -0
- Commands/reload.ts +56 -0
- Commands/skip.ts +33 -0
- Commands/stop.ts +40 -0
Commands/eval.ts
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ChatInputCommandInteraction, Message } from "discord.js";
|
2 |
+
|
3 |
+
export default {
|
4 |
+
data: {
|
5 |
+
name: "eval",
|
6 |
+
description: "Chạy mã JavaScript (chỉ chủ bot).",
|
7 |
+
toJSON() {
|
8 |
+
return {
|
9 |
+
name: "eval",
|
10 |
+
description: "Chạy mã JavaScript (chỉ chủ bot).",
|
11 |
+
};
|
12 |
+
},
|
13 |
+
},
|
14 |
+
ownersOnly: true,
|
15 |
+
async execute(input: ChatInputCommandInteraction | Message, args?: string[]) {
|
16 |
+
const code = args?.join(" ");
|
17 |
+
if (!code) {
|
18 |
+
return input instanceof Message
|
19 |
+
? input.reply("❌ Không có code để chạy.")
|
20 |
+
: input.reply({ content: "❌ Không có code để chạy.", ephemeral: true });
|
21 |
+
}
|
22 |
+
|
23 |
+
try {
|
24 |
+
let result = eval(code);
|
25 |
+
if (result instanceof Promise) result = await result;
|
26 |
+
|
27 |
+
const output = typeof result === "object" ? JSON.stringify(result, null, 2) : result;
|
28 |
+
|
29 |
+
if (input instanceof Message) {
|
30 |
+
await input.reply(`✅ Output:\n\`\`\`js\n${output}\n\`\`\``);
|
31 |
+
} else {
|
32 |
+
await input.reply({ content: `✅ Output:\n\`\`\`js\n${output}\n\`\`\``, ephemeral: true });
|
33 |
+
}
|
34 |
+
} catch (err) {
|
35 |
+
if (input instanceof Message) {
|
36 |
+
await input.reply(`❌ Error:\n\`\`\`${err}\`\`\``);
|
37 |
+
} else {
|
38 |
+
await input.reply({ content: `❌ Error:\n\`\`\`${err}\`\`\``, ephemeral: true });
|
39 |
+
}
|
40 |
+
}
|
41 |
+
},
|
42 |
+
};
|
Commands/help.ts
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ChatInputCommandInteraction, Message } from "discord.js";
|
2 |
+
import { commands } from "../index";
|
3 |
+
|
4 |
+
export default {
|
5 |
+
data: {
|
6 |
+
name: "help",
|
7 |
+
description: "Hiển thị danh sách lệnh có sẵn.",
|
8 |
+
toJSON() {
|
9 |
+
return {
|
10 |
+
name: "help",
|
11 |
+
description: "Hiển thị danh sách lệnh có sẵn.",
|
12 |
+
};
|
13 |
+
},
|
14 |
+
},
|
15 |
+
ownersOnly: false,
|
16 |
+
async execute(input: ChatInputCommandInteraction | Message) {
|
17 |
+
const commandList = commands
|
18 |
+
.map((cmd) => `- \`${cmd.data.name}\`: ${cmd.data.description}`)
|
19 |
+
.join("\n");
|
20 |
+
|
21 |
+
const replyText = `📜 **Danh sách lệnh:**\n${commandList}`;
|
22 |
+
|
23 |
+
if (input instanceof Message) {
|
24 |
+
await input.reply(replyText);
|
25 |
+
} else {
|
26 |
+
await input.reply({ content: replyText, ephemeral: true });
|
27 |
+
}
|
28 |
+
},
|
29 |
+
};
|
Commands/mass-dm.ts
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Colors, EmbedBuilder, Guild, Message } from "discord.js";
|
2 |
+
import type { Command } from "../types";
|
3 |
+
import { clients } from "..";
|
4 |
+
import { getJsonFromURL } from "../utils/discohook";
|
5 |
+
|
6 |
+
export default <Command>{
|
7 |
+
data: {
|
8 |
+
name: "mass-dm",
|
9 |
+
description: "Gửi tin nhắn đến toàn bộ thành viên trong server.",
|
10 |
+
toJSON() {
|
11 |
+
return {
|
12 |
+
name: "mass-dm",
|
13 |
+
description: "Gửi tin nhắn đến toàn bộ thành viên trong server.",
|
14 |
+
};
|
15 |
+
},
|
16 |
+
},
|
17 |
+
ownersOnly: true,
|
18 |
+
execute: async (message: Message, args?: string[]) => {
|
19 |
+
if (!message.guild || !args || args.length === 0) {
|
20 |
+
return message.reply("Vui lòng cung cấp nội dung tin nhắn.");
|
21 |
+
}
|
22 |
+
|
23 |
+
const contentInput = args.join(" ").trim();
|
24 |
+
const guild = message.guild as Guild;
|
25 |
+
|
26 |
+
const clientsInGuild = clients.filter((client) =>
|
27 |
+
client.guilds.cache.has(guild.id)
|
28 |
+
);
|
29 |
+
if (clientsInGuild.length === 0) {
|
30 |
+
return message.reply("❌ Không có client nào trong server.");
|
31 |
+
}
|
32 |
+
|
33 |
+
const DISCOHOOK_URL_REGEX =
|
34 |
+
/^(https?:\/\/)?(www\.)?(discohook\.app|discohook\.org)\/\?data=/;
|
35 |
+
let content = contentInput;
|
36 |
+
const embeds: any[] = [];
|
37 |
+
|
38 |
+
if (DISCOHOOK_URL_REGEX.test(contentInput)) {
|
39 |
+
const discohook = getJsonFromURL(contentInput);
|
40 |
+
if (discohook) {
|
41 |
+
if (discohook.embeds && discohook.embeds.length > 0) {
|
42 |
+
embeds.push(...discohook.embeds);
|
43 |
+
}
|
44 |
+
if (discohook.content) {
|
45 |
+
content = discohook.content;
|
46 |
+
}
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
const variables: Map<string, string> = new Map();
|
51 |
+
variables.set("guild.name", guild.name);
|
52 |
+
variables.set("guild.id", guild.id);
|
53 |
+
variables.set("guild.memberCount", guild.memberCount.toString());
|
54 |
+
|
55 |
+
const allMembers = guild.members.cache.filter((m) => !m.user.bot);
|
56 |
+
const done: { clientId: string; done: number; failed: number }[] =
|
57 |
+
clientsInGuild.map((client) => ({
|
58 |
+
clientId: client.user?.id as string,
|
59 |
+
done: 0,
|
60 |
+
failed: 0,
|
61 |
+
}));
|
62 |
+
|
63 |
+
const getTotallDone = () => done.reduce((acc, cur) => acc + cur.done, 0);
|
64 |
+
const getTotallFailed = () =>
|
65 |
+
done.reduce((acc, cur) => acc + cur.failed, 0);
|
66 |
+
const isDone = () => getTotallDone() + getTotallFailed() === allMembers.size;
|
67 |
+
|
68 |
+
const getEmbed = () =>
|
69 |
+
new EmbedBuilder()
|
70 |
+
.setTitle("📬 Mass DM Status")
|
71 |
+
.setDescription(
|
72 |
+
`Total: ${allMembers.size}\nDone: ${getTotallDone()}\nFailed: ${getTotallFailed()}\nStatus: ${isDone() ? "✅ Done" : "⏳ In Progress"}`
|
73 |
+
)
|
74 |
+
.setColor(isDone() ? Colors.Green : Colors.Yellow)
|
75 |
+
.setTimestamp();
|
76 |
+
|
77 |
+
const statusMessage = await message.reply({
|
78 |
+
embeds: [getEmbed()],
|
79 |
+
});
|
80 |
+
|
81 |
+
let clientIndex = 0;
|
82 |
+
for (const member of allMembers.values()) {
|
83 |
+
if (!clientsInGuild[clientIndex]) clientIndex = 0;
|
84 |
+
|
85 |
+
const client = clientsInGuild[clientIndex];
|
86 |
+
const clientDone = done.find((d) => d.clientId === client.user?.id)!;
|
87 |
+
clientIndex = (clientIndex + 1) % clientsInGuild.length;
|
88 |
+
|
89 |
+
// Tạo nội dung riêng biệt mỗi user
|
90 |
+
const personalizedVariables = new Map(variables);
|
91 |
+
personalizedVariables.set("user.username", member.user.username);
|
92 |
+
personalizedVariables.set("user.id", member.user.id);
|
93 |
+
personalizedVariables.set("user.tag", member.user.tag);
|
94 |
+
personalizedVariables.set("user.avatar", member.user.displayAvatarURL());
|
95 |
+
personalizedVariables.set("user.mention", member.user.toString());
|
96 |
+
personalizedVariables.set("user.nickname", member.nickname ?? member.user.username);
|
97 |
+
|
98 |
+
let personalizedContent = content;
|
99 |
+
for (const [key, value] of personalizedVariables.entries()) {
|
100 |
+
personalizedContent = personalizedContent.replace(new RegExp(`{${key}}`, "g"), value);
|
101 |
+
}
|
102 |
+
|
103 |
+
try {
|
104 |
+
await client.users.send(member.user.id, {
|
105 |
+
content: personalizedContent,
|
106 |
+
embeds: embeds,
|
107 |
+
});
|
108 |
+
clientDone.done++;
|
109 |
+
} catch (error) {
|
110 |
+
console.error(`❌ Không gửi được đến ${member.user.tag}:`, error);
|
111 |
+
clientDone.failed++;
|
112 |
+
}
|
113 |
+
|
114 |
+
try {
|
115 |
+
await statusMessage.edit({
|
116 |
+
embeds: [getEmbed()],
|
117 |
+
});
|
118 |
+
} catch (err) {
|
119 |
+
console.error("Không thể cập nhật tiến độ:", err);
|
120 |
+
}
|
121 |
+
|
122 |
+
await new Promise((res) => setTimeout(res, 400)); // delay nhẹ tránh bị rate limit
|
123 |
+
}
|
124 |
+
},
|
125 |
+
};
|
Commands/ping.ts
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ChatInputCommandInteraction, Message } from "discord.js";
|
2 |
+
|
3 |
+
export default {
|
4 |
+
data: {
|
5 |
+
name: "ping",
|
6 |
+
description: "Replies with Pong!",
|
7 |
+
toJSON() {
|
8 |
+
return { name: "ping", description: "Replies with Pong!" };
|
9 |
+
},
|
10 |
+
},
|
11 |
+
ownersOnly: false,
|
12 |
+
async execute(input: ChatInputCommandInteraction | Message) {
|
13 |
+
if (input instanceof Message) {
|
14 |
+
await input.reply("🏓 Pong! (prefix command)");
|
15 |
+
} else {
|
16 |
+
await input.reply("🏓 Pong! (slash command)");
|
17 |
+
}
|
18 |
+
},
|
19 |
+
};
|
Commands/play.ts
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Message, EmbedBuilder } from 'discord.js';
|
2 |
+
import {
|
3 |
+
joinVoiceChannel,
|
4 |
+
createAudioResource,
|
5 |
+
AudioPlayerStatus,
|
6 |
+
} from '@discordjs/voice';
|
7 |
+
import { get } from 'https';
|
8 |
+
import { MusicQueue } from '../utils/MusicQueue';
|
9 |
+
import { queues } from '../index';
|
10 |
+
import type { Command } from '../types';
|
11 |
+
|
12 |
+
async function playSong(queue: MusicQueue, guildId: string) {
|
13 |
+
if (queue.songs.length === 0) {
|
14 |
+
queue.playing = false;
|
15 |
+
return;
|
16 |
+
}
|
17 |
+
|
18 |
+
queue.playing = true;
|
19 |
+
queue.currentSong = queue.songs.shift()!;
|
20 |
+
|
21 |
+
try {
|
22 |
+
const stream = await new Promise<Readable>((resolve, reject) => {
|
23 |
+
get(queue.currentSong.url, (res) => {
|
24 |
+
if (res.statusCode !== 200) return reject(new Error('Failed to fetch MP3'));
|
25 |
+
resolve(res);
|
26 |
+
}).on('error', reject);
|
27 |
+
});
|
28 |
+
|
29 |
+
const resource = createAudioResource(stream);
|
30 |
+
queue.player.play(resource);
|
31 |
+
|
32 |
+
queue.player.once(AudioPlayerStatus.Idle, () => playSong(queue, guildId));
|
33 |
+
} catch (error) {
|
34 |
+
console.error('Error playing mp3:', error);
|
35 |
+
queue.playing = false;
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
export default <Command>{
|
40 |
+
data: {
|
41 |
+
name: 'play',
|
42 |
+
description: 'Phát nhạc từ link .mp3',
|
43 |
+
toJSON() {
|
44 |
+
return { name: 'play', description: 'Phát nhạc từ link .mp3' };
|
45 |
+
},
|
46 |
+
},
|
47 |
+
ownersOnly: false,
|
48 |
+
async execute(message: Message, args: string[]) {
|
49 |
+
const guildId = message.guild?.id;
|
50 |
+
if (!guildId) return message.reply('❌ Lệnh này chỉ hoạt động trong server.');
|
51 |
+
|
52 |
+
const voiceChannel = message.member?.voice.channel;
|
53 |
+
if (!voiceChannel) {
|
54 |
+
return message.reply('❌ Bạn cần tham gia voice channel để phát nhạc.');
|
55 |
+
}
|
56 |
+
|
57 |
+
const query = args.join(' ').trim();
|
58 |
+
if (!query || !query.endsWith('.mp3')) {
|
59 |
+
return message.reply('❌ Vui lòng cung cấp một link `.mp3` hợp lệ.');
|
60 |
+
}
|
61 |
+
|
62 |
+
if (!queues.has(guildId)) {
|
63 |
+
queues.set(guildId, new MusicQueue());
|
64 |
+
}
|
65 |
+
const queue = queues.get(guildId)!;
|
66 |
+
|
67 |
+
const song = {
|
68 |
+
title: query.split('/').pop() || 'MP3 File',
|
69 |
+
url: query,
|
70 |
+
duration: 0,
|
71 |
+
thumbnail: '',
|
72 |
+
requestedBy: message.author.id,
|
73 |
+
};
|
74 |
+
|
75 |
+
queue.songs.push(song);
|
76 |
+
|
77 |
+
if (!queue.playing) {
|
78 |
+
if (!queue.connection) {
|
79 |
+
queue.connection = joinVoiceChannel({
|
80 |
+
channelId: voiceChannel.id,
|
81 |
+
guildId: guildId,
|
82 |
+
adapterCreator: message.guild!.voiceAdapterCreator,
|
83 |
+
});
|
84 |
+
queue.connection.subscribe(queue.player);
|
85 |
+
}
|
86 |
+
playSong(queue, guildId);
|
87 |
+
}
|
88 |
+
|
89 |
+
const embed = new EmbedBuilder()
|
90 |
+
.setColor('#00ff00')
|
91 |
+
.setTitle('🎵 Đã thêm vào hàng đợi')
|
92 |
+
.setDescription(`**${song.title}**`)
|
93 |
+
.addFields(
|
94 |
+
{ name: 'Vị trí', value: queue.songs.length.toString(), inline: true },
|
95 |
+
{ name: 'Người yêu cầu', value: `<@${song.requestedBy}>`, inline: true }
|
96 |
+
);
|
97 |
+
|
98 |
+
await message.reply({ embeds: [embed] });
|
99 |
+
},
|
100 |
+
};
|
Commands/reload.ts
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ChatInputCommandInteraction, Message } from "discord.js";
|
2 |
+
import fs from "fs";
|
3 |
+
import path from "path";
|
4 |
+
import { commands } from "../index";
|
5 |
+
|
6 |
+
export default {
|
7 |
+
data: {
|
8 |
+
name: "reload",
|
9 |
+
description: "Tải lại toàn bộ lệnh từ thư mục Commands.",
|
10 |
+
toJSON() {
|
11 |
+
return {
|
12 |
+
name: "reload",
|
13 |
+
description: "Tải lại toàn bộ lệnh từ thư mục Commands.",
|
14 |
+
};
|
15 |
+
},
|
16 |
+
},
|
17 |
+
ownersOnly: true,
|
18 |
+
async execute(input: ChatInputCommandInteraction | Message) {
|
19 |
+
const dir = path.join(__dirname);
|
20 |
+
const newCommands = [];
|
21 |
+
|
22 |
+
try {
|
23 |
+
const files = fs.readdirSync(dir).filter((file) =>
|
24 |
+
file.endsWith(".ts") || file.endsWith(".js")
|
25 |
+
);
|
26 |
+
|
27 |
+
for (const file of files) {
|
28 |
+
if (file === "reload.ts" || file === "reload.js") continue;
|
29 |
+
|
30 |
+
const filePath = path.join(dir, file);
|
31 |
+
delete require.cache[require.resolve(filePath)];
|
32 |
+
|
33 |
+
const command = require(filePath).default;
|
34 |
+
if (command) newCommands.push(command);
|
35 |
+
}
|
36 |
+
|
37 |
+
commands.length = 0;
|
38 |
+
newCommands.forEach((cmd) => commands.push(cmd));
|
39 |
+
|
40 |
+
const replyText = `✅ Đã reload ${newCommands.length} lệnh.`;
|
41 |
+
|
42 |
+
if (input instanceof Message) {
|
43 |
+
await input.reply(replyText);
|
44 |
+
} else {
|
45 |
+
await input.reply({ content: replyText, ephemeral: true });
|
46 |
+
}
|
47 |
+
} catch (error) {
|
48 |
+
console.error(error);
|
49 |
+
if (input instanceof Message) {
|
50 |
+
await input.reply("❌ Lỗi khi reload command.");
|
51 |
+
} else {
|
52 |
+
await input.reply({ content: "❌ Lỗi khi reload command.", ephemeral: true });
|
53 |
+
}
|
54 |
+
}
|
55 |
+
},
|
56 |
+
};
|
Commands/skip.ts
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Message, EmbedBuilder } from 'discord.js';
|
2 |
+
import { MusicQueue } from '../utils/MusicQueue';
|
3 |
+
import { queues } from '../index';
|
4 |
+
import type { Command } from '../types';
|
5 |
+
|
6 |
+
export default <Command>{
|
7 |
+
data: {
|
8 |
+
name: 'skip',
|
9 |
+
description: 'Skip the current song',
|
10 |
+
toJSON() {
|
11 |
+
return { name: 'skip', description: 'Skip the current song' };
|
12 |
+
},
|
13 |
+
},
|
14 |
+
ownersOnly: false,
|
15 |
+
async execute(message: Message) {
|
16 |
+
const guildId = message.guild?.id;
|
17 |
+
if (!guildId) return message.reply('❌ This command can only be used in a server.');
|
18 |
+
|
19 |
+
const queue = queues.get(guildId);
|
20 |
+
if (!queue || !queue.playing || !queue.currentSong) {
|
21 |
+
return message.reply('❌ No song is currently playing!');
|
22 |
+
}
|
23 |
+
|
24 |
+
queue.player.stop();
|
25 |
+
|
26 |
+
const embed = new EmbedBuilder()
|
27 |
+
.setColor('#ff9900')
|
28 |
+
.setTitle('⏭️ Song Skipped')
|
29 |
+
.setDescription(`Skipped: **${queue.currentSong.title}**`);
|
30 |
+
|
31 |
+
await message.reply({ embeds: [embed] });
|
32 |
+
},
|
33 |
+
};
|
Commands/stop.ts
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Message, EmbedBuilder } from 'discord.js';
|
2 |
+
import { MusicQueue } from '../utils/MusicQueue';
|
3 |
+
import { queues } from '../index';
|
4 |
+
import type { Command } from '../types';
|
5 |
+
|
6 |
+
export default <Command>{
|
7 |
+
data: {
|
8 |
+
name: 'stop',
|
9 |
+
description: 'Stop playing and clear the queue',
|
10 |
+
toJSON() {
|
11 |
+
return { name: 'stop', description: 'Stop playing and clear the queue' };
|
12 |
+
},
|
13 |
+
},
|
14 |
+
ownersOnly: false,
|
15 |
+
async execute(message: Message) {
|
16 |
+
const guildId = message.guild?.id;
|
17 |
+
if (!guildId) return message.reply('❌ This command can only be used in a server.');
|
18 |
+
|
19 |
+
const queue = queues.get(guildId);
|
20 |
+
if (!queue || !queue.playing) {
|
21 |
+
return message.reply('❌ No music is currently playing!');
|
22 |
+
}
|
23 |
+
|
24 |
+
queue.songs = [];
|
25 |
+
queue.playing = false;
|
26 |
+
queue.currentSong = null;
|
27 |
+
queue.player.stop();
|
28 |
+
if (queue.connection) {
|
29 |
+
queue.connection.destroy();
|
30 |
+
queue.connection = null;
|
31 |
+
}
|
32 |
+
|
33 |
+
const embed = new EmbedBuilder()
|
34 |
+
.setColor('#ff0000')
|
35 |
+
.setTitle('⏹️ Music Stopped')
|
36 |
+
.setDescription('Stopped playing and cleared the queue.');
|
37 |
+
|
38 |
+
await message.reply({ embeds: [embed] });
|
39 |
+
},
|
40 |
+
};
|