105 lines
3.7 KiB
C#
105 lines
3.7 KiB
C#
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<string>? 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<SocketGuild> GetServers()
|
|
{
|
|
return _client?.Guilds ?? Enumerable.Empty<SocketGuild>();
|
|
}
|
|
|
|
// 특정 서버의 음성 채널 목록 가져오기
|
|
public IEnumerable<SocketVoiceChannel> GetVoiceChannels(ulong guildId)
|
|
{
|
|
var guild = _client?.GetGuild(guildId);
|
|
if (guild == null) return Enumerable.Empty<SocketVoiceChannel>();
|
|
|
|
// 일반 텍스트 채널은 빼고 음성 채널만 순서대로 정렬해서 반환
|
|
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("🔇 음성 채널에서 퇴장했습니다.");
|
|
}
|
|
}
|
|
}
|
|
} |