using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Discord; using Discord.Audio; using Discord.WebSocket; namespace AudioBotProject { public class DiscordBotManager { private DiscordSocketClient _client = null!; private IAudioClient? _audioClient; // 음성 채널 연결 객체 // UI 창(MainWindow)으로 메시지나 상태를 전달하기 위한 이벤트(Event) public event Action? OnLog; public event Action? OnReady; public async Task StartBotAsync(string botToken) { var config = new DiscordSocketConfig { GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.GuildVoiceStates }; _client = new DiscordSocketClient(config); // 디스코드에서 로그나 준비 완료 신호가 오면 우리 함수를 실행하도록 연결 _client.Log += LogAsync; _client.Ready += ReadyAsync; await _client.LoginAsync(TokenType.Bot, botToken); await _client.StartAsync(); } public async Task StopBotAsync() { if (_client != null) { await LeaveChannelAsync(); // 봇이 꺼지기 전에 채널에서 먼저 나옴 await _client.StopAsync(); await _client.LogoutAsync(); OnLog?.Invoke("봇이 디스코드 서버에서 로그아웃 되었습니다."); } } private Task LogAsync(LogMessage log) { OnLog?.Invoke(log.ToString()); // 화면의 로그창으로 텍스트 전송 return Task.CompletedTask; } private Task ReadyAsync() { OnLog?.Invoke($"✅ 봇 로그인 성공! 현재 봇 이름: {_client.CurrentUser.Username}"); OnReady?.Invoke(); // 화면 쪽에 "봇 준비 완료!" 신호 전송 return Task.CompletedTask; } public string GetBotName() => _client?.CurrentUser?.Username ?? "알 수 없음"; // 봇이 들어가 있는 서버(Guild) 목록 가져오기 public IEnumerable GetServers() { return _client?.Guilds ?? Enumerable.Empty(); } // 특정 서버의 음성 채널 목록 가져오기 public IEnumerable GetVoiceChannels(ulong guildId) { var guild = _client?.GetGuild(guildId); if (guild == null) return Enumerable.Empty(); // 일반 텍스트 채널은 빼고 음성 채널만 순서대로 정렬해서 반환 return guild.VoiceChannels.OrderBy(c => c.Position); } // 음성 채널 접속 public async Task JoinChannelAsync(ulong channelId) { if (_client == null) return; var channel = _client.GetChannel(channelId) as SocketVoiceChannel; if (channel != null) { // ConnectAsync()를 호출하면 디스코드 서버에 봇이 짠! 하고 등장합니다. _audioClient = await channel.ConnectAsync(); OnLog?.Invoke($"🔊 [{channel.Name}] 채널에 성공적으로 접속했습니다."); } } // 음성 채널 퇴장 public async Task LeaveChannelAsync() { if (_audioClient != null) { await _audioClient.StopAsync(); _audioClient.Dispose(); _audioClient = null; OnLog?.Invoke("🔇 음성 채널에서 퇴장했습니다."); } } } }