File size: 3,874 Bytes
7930560 20d4cea 7930560 20d4cea 7930560 20d4cea 7930560 20d4cea 7930560 20d4cea 7930560 20d4cea 7930560 20d4cea 7930560 20d4cea 7930560 20d4cea 7930560 20d4cea 7930560 20d4cea |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
import config from './config.json' with { type: 'json' };
import { Client, GatewayIntentBits, Partials } from 'discord.js';
import { readdirSync } from 'fs';
import { join } from 'path';
import type { Command } from './types';
import { MusicQueue } from './utils/MusicQueue';
import { SocksProxyAgent } from 'socks-proxy-agent'; // bun add socks-proxy-agent
const commandsDir = join(import.meta.dir, 'Commands');
const commands: Command[] = readdirSync(commandsDir)
.filter(file => file.endsWith('.ts') || file.endsWith('.js'))
.map(file => {
try {
const commandModule = require(join(commandsDir, file));
return commandModule.default;
} catch (error) {
console.error(`❌ Failed to load command ${file}:`, error);
return undefined;
}
})
.filter((cmd): cmd is Command => cmd !== undefined);
const clients: Client[] = [];
const queues = new Map<string, MusicQueue>();
config.tokens.forEach((token: string, index: number) => {
const proxyUrl = 'socks5h://admin1:[email protected]:80'; // 'socks5h' để resolve DNS qua proxy
const agent = new SocksProxyAgent(proxyUrl);
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildVoiceStates,
],
partials: [Partials.Channel],
http: {
agent: {
https: agent, // Áp dụng agent cho kết nối HTTPS
},
},
});
client.once('ready', () => {
console.log(`✅ Client ${index + 1} - ${client.user?.tag} is ready!`);
clients.push(client);
});
client.on('messageCreate', async message => {
if (message.author.bot || !message.content.startsWith(config.PREFIX)) return;
const args = message.content.slice(config.PREFIX.length).trim().split(/\s+/);
const commandName = args.shift()?.toLowerCase();
const command = commands.find(cmd => cmd?.data?.name === commandName);
if (!command) {
return message.reply(`❌ Lệnh \`${commandName}\` không tồn tại. Dùng \`${config.PREFIX}help\` để xem danh sách lệnh.`);
}
if (command.ownersOnly && !config.owners.includes(message.author.id)) {
return message.reply('⛔ Bạn không có quyền dùng lệnh này.');
}
try {
await command.execute(message, args, client);
} catch (error) {
console.error(`❌ Lỗi khi xử lý lệnh ${commandName}:`, error);
await message.reply('❌ Có lỗi xảy ra khi chạy lệnh.').catch(console.error);
}
});
client.on('voiceStateUpdate', (oldState, newState) => {
const queue = queues.get(oldState.guild.id);
if (!queue || !queue.connection) return;
const botVoiceChannel = queue.connection.joinConfig.channelId;
if (oldState.channelId === botVoiceChannel && newState.channelId !== botVoiceChannel) {
const channel = oldState.guild.channels.cache.get(botVoiceChannel);
if (channel) {
const members = channel.members.filter(member => !member.user.bot);
if (members.size === 0) {
queue.songs = [];
queue.playing = false;
queue.currentSong = null;
queue.player.stop();
if (queue.connection) {
queue.connection.destroy();
queue.connection = null;
}
console.log(`⏹️ Auto-stopped music in guild ${oldState.guild.name} - no users in voice channel`);
}
}
}
});
client.login(token).catch(error => {
console.error(`❌ Failed to login Client ${index + 1}:`, error);
});
});
export { clients, commands, queues };
process.on('unhandledRejection', error => {
console.error('❗ Unhandled promise rejection:', error);
});
process.on('uncaughtException', error => {
console.error('❗ Uncaught exception:', error);
}); |