1차 제작

기능은 다 만들었는데 테스트를 못해봄
그래서 잘 작동하는지 모름
집가서 테스트해봐야지
This commit is contained in:
2026-04-14 14:45:41 +09:00
parent 8589e16688
commit 9d14827e83
9 changed files with 1088 additions and 0 deletions

105
DiscordBotManager.cs Normal file
View File

@@ -0,0 +1,105 @@
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("🔇 음성 채널에서 퇴장했습니다.");
}
}
}
}