@@ -136,12 +136,12 @@ namespace Discord.Audio | |||
else | |||
return null; | |||
} | |||
private Task<DiscordAudioClient> CreateClient(Server server) | |||
private async Task<DiscordAudioClient> CreateClient(Server server) | |||
{ | |||
if (!Config.EnableMultiserver) | |||
{ | |||
_defaultClient.SetServerId(server.Id); | |||
return Task.FromResult(_defaultClient); | |||
await _defaultClient.SetServer(server.Id); | |||
return _defaultClient; | |||
} | |||
else | |||
throw new InvalidOperationException("Multiserver voice is not currently supported"); | |||
@@ -175,7 +175,7 @@ namespace Discord.Audio | |||
//CheckReady(true); | |||
var client = await CreateClient(channel.Server).ConfigureAwait(false); | |||
await client.Join(channel).ConfigureAwait(false); | |||
await client.JoinChannel(channel).ConfigureAwait(false); | |||
return client; | |||
} | |||
@@ -22,6 +22,7 @@ namespace Discord.Audio | |||
public ulong? ServerId => VoiceSocket.ServerId; | |||
public ulong? ChannelId => VoiceSocket.ChannelId; | |||
public ConnectionState State => VoiceSocket.State; | |||
public DiscordAudioClient(AudioService service, int id, Logger logger, GatewaySocket gatewaySocket) | |||
{ | |||
@@ -76,51 +77,57 @@ namespace Discord.Audio | |||
_voiceSocket.ParentCancelToken = _cancelToken; | |||
};*/ | |||
GatewaySocket.ReceivedDispatch += OnReceivedDispatch; | |||
} | |||
} | |||
internal void SetServerId(ulong serverId) | |||
internal async Task SetServer(ulong serverId) | |||
{ | |||
VoiceSocket.ServerId = serverId; | |||
if (serverId != VoiceSocket.ServerId) | |||
{ | |||
await Disconnect().ConfigureAwait(false); | |||
VoiceSocket.ServerId = serverId; | |||
VoiceSocket.ChannelId = null; | |||
SendVoiceUpdate(); | |||
} | |||
} | |||
public Task Join(Channel channel) | |||
public Task JoinChannel(Channel channel) | |||
{ | |||
if (channel == null) throw new ArgumentNullException(nameof(channel)); | |||
ulong? serverId = channel.Server?.Id; | |||
if (serverId != ServerId) | |||
var serverId = channel.Server?.Id; | |||
var channelId = channel.Id; | |||
if (serverId != ServerId) | |||
throw new InvalidOperationException("Cannot join a channel on a different server than this voice client."); | |||
if (channelId == VoiceSocket.ChannelId) | |||
return TaskHelper.CompletedTask; | |||
//CheckReady(checkVoice: true); | |||
return Task.Run(async () => | |||
{ | |||
_connectionLock.WaitOne(); | |||
GatewaySocket.ReceivedDispatch += OnReceivedDispatch; | |||
try | |||
{ | |||
await VoiceSocket.Disconnect().ConfigureAwait(false); | |||
if (State != ConnectionState.Disconnected) | |||
await Disconnect().ConfigureAwait(false); | |||
_cancelTokenSource = new CancellationTokenSource(); | |||
var cancelToken = _cancelTokenSource.Token; | |||
VoiceSocket.ParentCancelToken = cancelToken; | |||
VoiceSocket.ChannelId = channel.Id; | |||
GatewaySocket.SendUpdateVoice(channel.Server.Id, channel.Id, | |||
(Service.Config.Mode | AudioMode.Outgoing) == 0, | |||
(Service.Config.Mode | AudioMode.Incoming) == 0); | |||
VoiceSocket.ChannelId = channelId; | |||
SendVoiceUpdate(); | |||
VoiceSocket.WaitForConnection(cancelToken); | |||
} | |||
finally | |||
{ | |||
GatewaySocket.ReceivedDispatch -= OnReceivedDispatch; | |||
_connectionLock.Release(); | |||
} | |||
}); | |||
} | |||
public Task Disconnect() | |||
{ | |||
GatewaySocket.ReceivedDispatch -= OnReceivedDispatch; | |||
return VoiceSocket.Disconnect(); | |||
} | |||
=> VoiceSocket.Disconnect(); | |||
private async void OnReceivedDispatch(object sender, WebSocketEventEventArgs e) | |||
{ | |||
@@ -172,12 +179,22 @@ namespace Discord.Audio | |||
} | |||
/// <summary> Returns a task that completes once the voice output buffer is empty. </summary> | |||
public Task Wait() | |||
public void Wait() | |||
{ | |||
//CheckReady(checkVoice: true); | |||
VoiceSocket.WaitForQueue(); | |||
return TaskHelper.CompletedTask; | |||
} | |||
private void SendVoiceUpdate() | |||
{ | |||
var serverId = VoiceSocket.ServerId; | |||
if (serverId != null) | |||
{ | |||
GatewaySocket.SendUpdateVoice(serverId, VoiceSocket.ChannelId, | |||
(Service.Config.Mode | AudioMode.Outgoing) == 0, | |||
(Service.Config.Mode | AudioMode.Incoming) == 0); | |||
} | |||
} | |||
} | |||
} |
@@ -101,13 +101,15 @@ namespace Discord.Net.WebSockets | |||
_sendThread = new Thread(new ThreadStart(() => SendVoiceAsync(CancelToken))); | |||
_sendThread.IsBackground = true; | |||
_sendThread.Start(); | |||
} | |||
if ((_config.Mode & AudioMode.Incoming) != 0) | |||
{ | |||
_receiveThread = new Thread(new ThreadStart(() => ReceiveVoiceAsync(CancelToken))); | |||
_receiveThread.IsBackground = true; | |||
_receiveThread.Start(); | |||
} | |||
/*if ((_config.Mode & AudioMode.Incoming) != 0) | |||
{*/ | |||
_receiveThread = new Thread(new ThreadStart(() => ReceiveVoiceAsync(CancelToken))); | |||
_receiveThread.IsBackground = true; | |||
_receiveThread.Start(); | |||
/*} | |||
else | |||
tasks.Add(Task.Run(() => ReceiveVoiceAsync(CancelToken)));*/ | |||
SendIdentify(); | |||
@@ -10,10 +10,10 @@ namespace Discord.API.Client.GatewaySocket | |||
object IWebSocketMessage.Payload => this; | |||
bool IWebSocketMessage.IsPrivate => false; | |||
[JsonProperty("guild_id"), JsonConverter(typeof(LongStringConverter))] | |||
public ulong GuildId { get; set; } | |||
[JsonProperty("channel_id"), JsonConverter(typeof(LongStringConverter))] | |||
public ulong ChannelId { get; set; } | |||
[JsonProperty("guild_id"), JsonConverter(typeof(NullableLongStringConverter))] | |||
public ulong? GuildId { get; set; } | |||
[JsonProperty("channel_id"), JsonConverter(typeof(NullableLongStringConverter))] | |||
public ulong? ChannelId { get; set; } | |||
[JsonProperty("self_mute")] | |||
public bool IsSelfMuted { get; set; } | |||
[JsonProperty("self_deaf")] | |||
@@ -173,7 +173,7 @@ namespace Discord.Net.WebSockets | |||
IdleSince = idleSince, | |||
Game = gameName != null ? new UpdateStatusCommand.GameInfo { Name = gameName } : null | |||
}); | |||
public void SendUpdateVoice(ulong serverId, ulong channelId, bool isSelfMuted, bool isSelfDeafened) | |||
public void SendUpdateVoice(ulong? serverId, ulong? channelId, bool isSelfMuted, bool isSelfDeafened) | |||
=> QueueMessage(new UpdateVoiceCommand { GuildId = serverId, ChannelId = channelId, IsSelfMuted = isSelfMuted, IsSelfDeafened = isSelfDeafened }); | |||
public void SendRequestMembers(ulong serverId, string query, int limit) | |||
=> QueueMessage(new RequestMembersCommand { GuildId = serverId, Query = query, Limit = limit }); | |||