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(); config.tokens.forEach((token: string, index: number) => { const proxyUrl = 'socks5h://admin1:thanhtai123@74.81.54.129: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); });