Internally exposed several ApiClient props
This commit is contained in:
@@ -31,12 +31,10 @@ namespace Discord.API
|
|||||||
|
|
||||||
protected readonly JsonSerializer _serializer;
|
protected readonly JsonSerializer _serializer;
|
||||||
protected readonly SemaphoreSlim _stateLock;
|
protected readonly SemaphoreSlim _stateLock;
|
||||||
private readonly RestClientProvider _restClientProvider;
|
private readonly RestClientProvider RestClientProvider;
|
||||||
|
|
||||||
protected string _authToken;
|
|
||||||
protected bool _isDisposed;
|
protected bool _isDisposed;
|
||||||
private CancellationTokenSource _loginCancelToken;
|
private CancellationTokenSource _loginCancelToken;
|
||||||
private IRestClient _restClient;
|
|
||||||
private bool _fetchCurrentUser;
|
private bool _fetchCurrentUser;
|
||||||
|
|
||||||
public RetryMode DefaultRetryMode { get; }
|
public RetryMode DefaultRetryMode { get; }
|
||||||
@@ -45,6 +43,8 @@ namespace Discord.API
|
|||||||
|
|
||||||
public LoginState LoginState { get; private set; }
|
public LoginState LoginState { get; private set; }
|
||||||
public TokenType AuthTokenType { get; private set; }
|
public TokenType AuthTokenType { get; private set; }
|
||||||
|
internal string AuthToken { get; private set; }
|
||||||
|
internal IRestClient RestClient { get; private set; }
|
||||||
internal User CurrentUser { get; private set; }
|
internal User CurrentUser { get; private set; }
|
||||||
|
|
||||||
public ulong? CurrentUserId => CurrentUser?.Id;
|
public ulong? CurrentUserId => CurrentUser?.Id;
|
||||||
@@ -52,7 +52,7 @@ namespace Discord.API
|
|||||||
public DiscordRestApiClient(RestClientProvider restClientProvider, string userAgent, RetryMode defaultRetryMode = RetryMode.AlwaysRetry,
|
public DiscordRestApiClient(RestClientProvider restClientProvider, string userAgent, RetryMode defaultRetryMode = RetryMode.AlwaysRetry,
|
||||||
JsonSerializer serializer = null, bool fetchCurrentUser = true)
|
JsonSerializer serializer = null, bool fetchCurrentUser = true)
|
||||||
{
|
{
|
||||||
_restClientProvider = restClientProvider;
|
RestClientProvider = restClientProvider;
|
||||||
UserAgent = userAgent;
|
UserAgent = userAgent;
|
||||||
DefaultRetryMode = defaultRetryMode;
|
DefaultRetryMode = defaultRetryMode;
|
||||||
_serializer = serializer ?? new JsonSerializer { DateFormatString = "yyyy-MM-ddTHH:mm:ssZ", ContractResolver = new DiscordContractResolver() };
|
_serializer = serializer ?? new JsonSerializer { DateFormatString = "yyyy-MM-ddTHH:mm:ssZ", ContractResolver = new DiscordContractResolver() };
|
||||||
@@ -65,10 +65,10 @@ namespace Discord.API
|
|||||||
}
|
}
|
||||||
internal void SetBaseUrl(string baseUrl)
|
internal void SetBaseUrl(string baseUrl)
|
||||||
{
|
{
|
||||||
_restClient = _restClientProvider(baseUrl);
|
RestClient = RestClientProvider(baseUrl);
|
||||||
_restClient.SetHeader("accept", "*/*");
|
RestClient.SetHeader("accept", "*/*");
|
||||||
_restClient.SetHeader("user-agent", UserAgent);
|
RestClient.SetHeader("user-agent", UserAgent);
|
||||||
_restClient.SetHeader("authorization", GetPrefixedToken(AuthTokenType, _authToken));
|
RestClient.SetHeader("authorization", GetPrefixedToken(AuthTokenType, AuthToken));
|
||||||
}
|
}
|
||||||
internal static string GetPrefixedToken(TokenType tokenType, string token)
|
internal static string GetPrefixedToken(TokenType tokenType, string token)
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ namespace Discord.API
|
|||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
_loginCancelToken?.Dispose();
|
_loginCancelToken?.Dispose();
|
||||||
(_restClient as IDisposable)?.Dispose();
|
(RestClient as IDisposable)?.Dispose();
|
||||||
}
|
}
|
||||||
_isDisposed = true;
|
_isDisposed = true;
|
||||||
}
|
}
|
||||||
@@ -118,13 +118,13 @@ namespace Discord.API
|
|||||||
_loginCancelToken = new CancellationTokenSource();
|
_loginCancelToken = new CancellationTokenSource();
|
||||||
|
|
||||||
AuthTokenType = TokenType.User;
|
AuthTokenType = TokenType.User;
|
||||||
_authToken = null;
|
AuthToken = null;
|
||||||
await RequestQueue.SetCancelTokenAsync(_loginCancelToken.Token).ConfigureAwait(false);
|
await RequestQueue.SetCancelTokenAsync(_loginCancelToken.Token).ConfigureAwait(false);
|
||||||
_restClient.SetCancelToken(_loginCancelToken.Token);
|
RestClient.SetCancelToken(_loginCancelToken.Token);
|
||||||
|
|
||||||
AuthTokenType = tokenType;
|
AuthTokenType = tokenType;
|
||||||
_authToken = token;
|
AuthToken = token;
|
||||||
_restClient.SetHeader("authorization", GetPrefixedToken(AuthTokenType, _authToken));
|
RestClient.SetHeader("authorization", GetPrefixedToken(AuthTokenType, AuthToken));
|
||||||
|
|
||||||
if (_fetchCurrentUser)
|
if (_fetchCurrentUser)
|
||||||
CurrentUser = await GetMyUserAsync(new RequestOptions { IgnoreState = true, RetryMode = RetryMode.AlwaysRetry }).ConfigureAwait(false);
|
CurrentUser = await GetMyUserAsync(new RequestOptions { IgnoreState = true, RetryMode = RetryMode.AlwaysRetry }).ConfigureAwait(false);
|
||||||
@@ -160,7 +160,7 @@ namespace Discord.API
|
|||||||
await RequestQueue.ClearAsync().ConfigureAwait(false);
|
await RequestQueue.ClearAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
await RequestQueue.SetCancelTokenAsync(CancellationToken.None).ConfigureAwait(false);
|
await RequestQueue.SetCancelTokenAsync(CancellationToken.None).ConfigureAwait(false);
|
||||||
_restClient.SetCancelToken(CancellationToken.None);
|
RestClient.SetCancelToken(CancellationToken.None);
|
||||||
|
|
||||||
CurrentUser = null;
|
CurrentUser = null;
|
||||||
LoginState = LoginState.LoggedOut;
|
LoginState = LoginState.LoggedOut;
|
||||||
@@ -181,7 +181,7 @@ namespace Discord.API
|
|||||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||||
|
|
||||||
var request = new RestRequest(_restClient, method, endpoint, options);
|
var request = new RestRequest(RestClient, method, endpoint, options);
|
||||||
await SendInternalAsync(method, endpoint, request).ConfigureAwait(false);
|
await SendInternalAsync(method, endpoint, request).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ namespace Discord.API
|
|||||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||||
|
|
||||||
var json = payload != null ? SerializeJson(payload) : null;
|
var json = payload != null ? SerializeJson(payload) : null;
|
||||||
var request = new JsonRestRequest(_restClient, method, endpoint, json, options);
|
var request = new JsonRestRequest(RestClient, method, endpoint, json, options);
|
||||||
await SendInternalAsync(method, endpoint, request).ConfigureAwait(false);
|
await SendInternalAsync(method, endpoint, request).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ namespace Discord.API
|
|||||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||||
|
|
||||||
var request = new MultipartRestRequest(_restClient, method, endpoint, multipartArgs, options);
|
var request = new MultipartRestRequest(RestClient, method, endpoint, multipartArgs, options);
|
||||||
await SendInternalAsync(method, endpoint, request).ConfigureAwait(false);
|
await SendInternalAsync(method, endpoint, request).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ namespace Discord.API
|
|||||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||||
|
|
||||||
var request = new RestRequest(_restClient, method, endpoint, options);
|
var request = new RestRequest(RestClient, method, endpoint, options);
|
||||||
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
|
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ namespace Discord.API
|
|||||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||||
|
|
||||||
var json = payload != null ? SerializeJson(payload) : null;
|
var json = payload != null ? SerializeJson(payload) : null;
|
||||||
var request = new JsonRestRequest(_restClient, method, endpoint, json, options);
|
var request = new JsonRestRequest(RestClient, method, endpoint, json, options);
|
||||||
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
|
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ namespace Discord.API
|
|||||||
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId;
|
||||||
options.IsClientBucket = AuthTokenType == TokenType.User;
|
options.IsClientBucket = AuthTokenType == TokenType.User;
|
||||||
|
|
||||||
var request = new MultipartRestRequest(_restClient, method, endpoint, multipartArgs, options);
|
var request = new MultipartRestRequest(RestClient, method, endpoint, multipartArgs, options);
|
||||||
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
|
return DeserializeJson<TResponse>(await SendInternalAsync(method, endpoint, request).ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +294,7 @@ namespace Discord.API
|
|||||||
var ids = new BucketIds(channelId: channelId);
|
var ids = new BucketIds(channelId: channelId);
|
||||||
return await SendAsync<Channel>("GET", () => $"channels/{channelId}", ids, options: options).ConfigureAwait(false);
|
return await SendAsync<Channel>("GET", () => $"channels/{channelId}", ids, options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; }
|
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
|
||||||
}
|
}
|
||||||
public async Task<Channel> GetChannelAsync(ulong guildId, ulong channelId, RequestOptions options = null)
|
public async Task<Channel> GetChannelAsync(ulong guildId, ulong channelId, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
@@ -310,7 +310,7 @@ namespace Discord.API
|
|||||||
return null;
|
return null;
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; }
|
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
|
||||||
}
|
}
|
||||||
public async Task<IReadOnlyCollection<Channel>> GetGuildChannelsAsync(ulong guildId, RequestOptions options = null)
|
public async Task<IReadOnlyCollection<Channel>> GetGuildChannelsAsync(ulong guildId, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
@@ -365,8 +365,8 @@ namespace Discord.API
|
|||||||
{
|
{
|
||||||
Preconditions.NotEqual(channelId, 0, nameof(channelId));
|
Preconditions.NotEqual(channelId, 0, nameof(channelId));
|
||||||
Preconditions.NotNull(args, nameof(args));
|
Preconditions.NotNull(args, nameof(args));
|
||||||
Preconditions.GreaterThan(args.Bitrate, 8000, nameof(args.Bitrate));
|
Preconditions.AtLeast(args.Bitrate, 8000, nameof(args.Bitrate));
|
||||||
Preconditions.AtLeast(args.UserLimit, 0, nameof(args.Bitrate));
|
Preconditions.AtLeast(args.UserLimit, 0, nameof(args.UserLimit));
|
||||||
Preconditions.AtLeast(args.Position, 0, nameof(args.Position));
|
Preconditions.AtLeast(args.Position, 0, nameof(args.Position));
|
||||||
Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name));
|
Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name));
|
||||||
options = RequestOptions.CreateOrClone(options);
|
options = RequestOptions.CreateOrClone(options);
|
||||||
@@ -407,7 +407,7 @@ namespace Discord.API
|
|||||||
var ids = new BucketIds(channelId: channelId);
|
var ids = new BucketIds(channelId: channelId);
|
||||||
return await SendAsync<Message>("GET", () => $"channels/{channelId}/messages/{messageId}", ids, options: options).ConfigureAwait(false);
|
return await SendAsync<Message>("GET", () => $"channels/{channelId}/messages/{messageId}", ids, options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; }
|
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
|
||||||
}
|
}
|
||||||
public async Task<IReadOnlyCollection<Message>> GetChannelMessagesAsync(ulong channelId, GetChannelMessagesParams args, RequestOptions options = null)
|
public async Task<IReadOnlyCollection<Message>> GetChannelMessagesAsync(ulong channelId, GetChannelMessagesParams args, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
@@ -676,7 +676,7 @@ namespace Discord.API
|
|||||||
var ids = new BucketIds(guildId: guildId);
|
var ids = new BucketIds(guildId: guildId);
|
||||||
return await SendAsync<Guild>("GET", () => $"guilds/{guildId}", ids, options: options).ConfigureAwait(false);
|
return await SendAsync<Guild>("GET", () => $"guilds/{guildId}", ids, options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; }
|
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
|
||||||
}
|
}
|
||||||
public async Task<Guild> CreateGuildAsync(CreateGuildParams args, RequestOptions options = null)
|
public async Task<Guild> CreateGuildAsync(CreateGuildParams args, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
@@ -779,7 +779,7 @@ namespace Discord.API
|
|||||||
var ids = new BucketIds(guildId: guildId);
|
var ids = new BucketIds(guildId: guildId);
|
||||||
return await SendAsync<GuildEmbed>("GET", () => $"guilds/{guildId}/embed", ids, options: options).ConfigureAwait(false);
|
return await SendAsync<GuildEmbed>("GET", () => $"guilds/{guildId}/embed", ids, options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; }
|
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
|
||||||
}
|
}
|
||||||
public async Task<GuildEmbed> ModifyGuildEmbedAsync(ulong guildId, Rest.ModifyGuildEmbedParams args, RequestOptions options = null)
|
public async Task<GuildEmbed> ModifyGuildEmbedAsync(ulong guildId, Rest.ModifyGuildEmbedParams args, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
@@ -859,7 +859,7 @@ namespace Discord.API
|
|||||||
{
|
{
|
||||||
return await SendAsync<Invite>("GET", () => $"invites/{inviteId}", new BucketIds(), options: options).ConfigureAwait(false);
|
return await SendAsync<Invite>("GET", () => $"invites/{inviteId}", new BucketIds(), options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; }
|
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
|
||||||
}
|
}
|
||||||
public async Task<IReadOnlyCollection<InviteMetadata>> GetGuildInvitesAsync(ulong guildId, RequestOptions options = null)
|
public async Task<IReadOnlyCollection<InviteMetadata>> GetGuildInvitesAsync(ulong guildId, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
@@ -915,7 +915,7 @@ namespace Discord.API
|
|||||||
var ids = new BucketIds(guildId: guildId);
|
var ids = new BucketIds(guildId: guildId);
|
||||||
return await SendAsync<GuildMember>("GET", () => $"guilds/{guildId}/members/{userId}", ids, options: options).ConfigureAwait(false);
|
return await SendAsync<GuildMember>("GET", () => $"guilds/{guildId}/members/{userId}", ids, options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; }
|
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
|
||||||
}
|
}
|
||||||
public async Task<IReadOnlyCollection<GuildMember>> GetGuildMembersAsync(ulong guildId, GetGuildMembersParams args, RequestOptions options = null)
|
public async Task<IReadOnlyCollection<GuildMember>> GetGuildMembersAsync(ulong guildId, GetGuildMembersParams args, RequestOptions options = null)
|
||||||
{
|
{
|
||||||
@@ -1032,7 +1032,7 @@ namespace Discord.API
|
|||||||
{
|
{
|
||||||
return await SendAsync<User>("GET", () => $"users/{userId}", new BucketIds(), options: options).ConfigureAwait(false);
|
return await SendAsync<User>("GET", () => $"users/{userId}", new BucketIds(), options: options).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; }
|
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//Current User/DMs
|
//Current User/DMs
|
||||||
|
|||||||
@@ -26,9 +26,10 @@ namespace Discord.API
|
|||||||
public event Func<Exception, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } }
|
public event Func<Exception, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } }
|
||||||
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
|
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
|
||||||
|
|
||||||
private readonly IWebSocketClient _gatewayClient;
|
|
||||||
private CancellationTokenSource _connectCancelToken;
|
private CancellationTokenSource _connectCancelToken;
|
||||||
private string _gatewayUrl;
|
private string _gatewayUrl;
|
||||||
|
|
||||||
|
internal IWebSocketClient WebSocketClient { get; }
|
||||||
|
|
||||||
public ConnectionState ConnectionState { get; private set; }
|
public ConnectionState ConnectionState { get; private set; }
|
||||||
|
|
||||||
@@ -36,9 +37,9 @@ namespace Discord.API
|
|||||||
RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null)
|
RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null)
|
||||||
: base(restClientProvider, userAgent, defaultRetryMode, serializer, true)
|
: base(restClientProvider, userAgent, defaultRetryMode, serializer, true)
|
||||||
{
|
{
|
||||||
_gatewayClient = webSocketProvider();
|
WebSocketClient = webSocketProvider();
|
||||||
//_gatewayClient.SetHeader("user-agent", DiscordConfig.UserAgent); (Causes issues in .NET Framework 4.6+)
|
//WebSocketClient.SetHeader("user-agent", DiscordConfig.UserAgent); (Causes issues in .NET Framework 4.6+)
|
||||||
_gatewayClient.BinaryMessage += async (data, index, count) =>
|
WebSocketClient.BinaryMessage += async (data, index, count) =>
|
||||||
{
|
{
|
||||||
using (var compressed = new MemoryStream(data, index + 2, count - 2))
|
using (var compressed = new MemoryStream(data, index + 2, count - 2))
|
||||||
using (var decompressed = new MemoryStream())
|
using (var decompressed = new MemoryStream())
|
||||||
@@ -54,7 +55,7 @@ namespace Discord.API
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_gatewayClient.TextMessage += async text =>
|
WebSocketClient.TextMessage += async text =>
|
||||||
{
|
{
|
||||||
using (var reader = new StringReader(text))
|
using (var reader = new StringReader(text))
|
||||||
using (var jsonReader = new JsonTextReader(reader))
|
using (var jsonReader = new JsonTextReader(reader))
|
||||||
@@ -63,7 +64,7 @@ namespace Discord.API
|
|||||||
await _receivedGatewayEvent.InvokeAsync((GatewayOpCode)msg.Operation, msg.Sequence, msg.Type, msg.Payload).ConfigureAwait(false);
|
await _receivedGatewayEvent.InvokeAsync((GatewayOpCode)msg.Operation, msg.Sequence, msg.Type, msg.Payload).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_gatewayClient.Closed += async ex =>
|
WebSocketClient.Closed += async ex =>
|
||||||
{
|
{
|
||||||
await DisconnectAsync().ConfigureAwait(false);
|
await DisconnectAsync().ConfigureAwait(false);
|
||||||
await _disconnectedEvent.InvokeAsync(ex).ConfigureAwait(false);
|
await _disconnectedEvent.InvokeAsync(ex).ConfigureAwait(false);
|
||||||
@@ -76,7 +77,7 @@ namespace Discord.API
|
|||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
_connectCancelToken?.Dispose();
|
_connectCancelToken?.Dispose();
|
||||||
(_gatewayClient as IDisposable)?.Dispose();
|
(WebSocketClient as IDisposable)?.Dispose();
|
||||||
}
|
}
|
||||||
_isDisposed = true;
|
_isDisposed = true;
|
||||||
}
|
}
|
||||||
@@ -95,22 +96,22 @@ namespace Discord.API
|
|||||||
{
|
{
|
||||||
if (LoginState != LoginState.LoggedIn)
|
if (LoginState != LoginState.LoggedIn)
|
||||||
throw new InvalidOperationException("You must log in before connecting.");
|
throw new InvalidOperationException("You must log in before connecting.");
|
||||||
if (_gatewayClient == null)
|
if (WebSocketClient == null)
|
||||||
throw new NotSupportedException("This client is not configured with websocket support.");
|
throw new NotSupportedException("This client is not configured with websocket support.");
|
||||||
|
|
||||||
ConnectionState = ConnectionState.Connecting;
|
ConnectionState = ConnectionState.Connecting;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_connectCancelToken = new CancellationTokenSource();
|
_connectCancelToken = new CancellationTokenSource();
|
||||||
if (_gatewayClient != null)
|
if (WebSocketClient != null)
|
||||||
_gatewayClient.SetCancelToken(_connectCancelToken.Token);
|
WebSocketClient.SetCancelToken(_connectCancelToken.Token);
|
||||||
|
|
||||||
if (_gatewayUrl == null)
|
if (_gatewayUrl == null)
|
||||||
{
|
{
|
||||||
var gatewayResponse = await GetGatewayAsync().ConfigureAwait(false);
|
var gatewayResponse = await GetGatewayAsync().ConfigureAwait(false);
|
||||||
_gatewayUrl = $"{gatewayResponse.Url}?v={DiscordConfig.APIVersion}&encoding={DiscordSocketConfig.GatewayEncoding}";
|
_gatewayUrl = $"{gatewayResponse.Url}?v={DiscordConfig.APIVersion}&encoding={DiscordSocketConfig.GatewayEncoding}";
|
||||||
}
|
}
|
||||||
await _gatewayClient.ConnectAsync(_gatewayUrl).ConfigureAwait(false);
|
await WebSocketClient.ConnectAsync(_gatewayUrl).ConfigureAwait(false);
|
||||||
|
|
||||||
ConnectionState = ConnectionState.Connected;
|
ConnectionState = ConnectionState.Connected;
|
||||||
}
|
}
|
||||||
@@ -142,7 +143,7 @@ namespace Discord.API
|
|||||||
}
|
}
|
||||||
internal override async Task DisconnectInternalAsync()
|
internal override async Task DisconnectInternalAsync()
|
||||||
{
|
{
|
||||||
if (_gatewayClient == null)
|
if (WebSocketClient == null)
|
||||||
throw new NotSupportedException("This client is not configured with websocket support.");
|
throw new NotSupportedException("This client is not configured with websocket support.");
|
||||||
|
|
||||||
if (ConnectionState == ConnectionState.Disconnected) return;
|
if (ConnectionState == ConnectionState.Disconnected) return;
|
||||||
@@ -151,7 +152,7 @@ namespace Discord.API
|
|||||||
try { _connectCancelToken?.Cancel(false); }
|
try { _connectCancelToken?.Cancel(false); }
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
await _gatewayClient.DisconnectAsync().ConfigureAwait(false);
|
await WebSocketClient.DisconnectAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
ConnectionState = ConnectionState.Disconnected;
|
ConnectionState = ConnectionState.Disconnected;
|
||||||
}
|
}
|
||||||
@@ -168,7 +169,7 @@ namespace Discord.API
|
|||||||
payload = new SocketFrame { Operation = (int)opCode, Payload = payload };
|
payload = new SocketFrame { Operation = (int)opCode, Payload = payload };
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
bytes = Encoding.UTF8.GetBytes(SerializeJson(payload));
|
bytes = Encoding.UTF8.GetBytes(SerializeJson(payload));
|
||||||
await RequestQueue.SendAsync(new WebSocketRequest(_gatewayClient, null, bytes, true, options)).ConfigureAwait(false);
|
await RequestQueue.SendAsync(new WebSocketRequest(WebSocketClient, null, bytes, true, options)).ConfigureAwait(false);
|
||||||
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
|
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +193,7 @@ namespace Discord.API
|
|||||||
};
|
};
|
||||||
var msg = new IdentifyParams()
|
var msg = new IdentifyParams()
|
||||||
{
|
{
|
||||||
Token = _authToken,
|
Token = AuthToken,
|
||||||
Properties = props,
|
Properties = props,
|
||||||
LargeThreshold = largeThreshold,
|
LargeThreshold = largeThreshold,
|
||||||
UseCompression = useCompression,
|
UseCompression = useCompression,
|
||||||
@@ -207,7 +208,7 @@ namespace Discord.API
|
|||||||
options = RequestOptions.CreateOrClone(options);
|
options = RequestOptions.CreateOrClone(options);
|
||||||
var msg = new ResumeParams()
|
var msg = new ResumeParams()
|
||||||
{
|
{
|
||||||
Token = _authToken,
|
Token = AuthToken,
|
||||||
SessionId = sessionId,
|
SessionId = sessionId,
|
||||||
Sequence = lastSeq
|
Sequence = lastSeq
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ namespace Discord.Audio
|
|||||||
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
|
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
|
||||||
|
|
||||||
private readonly JsonSerializer _serializer;
|
private readonly JsonSerializer _serializer;
|
||||||
private readonly IWebSocketClient _webSocketClient;
|
|
||||||
private readonly SemaphoreSlim _connectionLock;
|
private readonly SemaphoreSlim _connectionLock;
|
||||||
private CancellationTokenSource _connectCancelToken;
|
private CancellationTokenSource _connectCancelToken;
|
||||||
private IUdpSocket _udp;
|
private IUdpSocket _udp;
|
||||||
private bool _isDisposed;
|
private bool _isDisposed;
|
||||||
|
|
||||||
public ulong GuildId { get; }
|
public ulong GuildId { get; }
|
||||||
|
internal IWebSocketClient WebSocketClient { get; }
|
||||||
public ConnectionState ConnectionState { get; private set; }
|
public ConnectionState ConnectionState { get; private set; }
|
||||||
|
|
||||||
internal DiscordVoiceAPIClient(ulong guildId, WebSocketProvider webSocketProvider, UdpSocketProvider udpSocketProvider, JsonSerializer serializer = null)
|
internal DiscordVoiceAPIClient(ulong guildId, WebSocketProvider webSocketProvider, UdpSocketProvider udpSocketProvider, JsonSerializer serializer = null)
|
||||||
@@ -63,9 +63,9 @@ namespace Discord.Audio
|
|||||||
await _receivedPacketEvent.InvokeAsync(data).ConfigureAwait(false);
|
await _receivedPacketEvent.InvokeAsync(data).ConfigureAwait(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
_webSocketClient = webSocketProvider();
|
WebSocketClient = webSocketProvider();
|
||||||
//_gatewayClient.SetHeader("user-agent", DiscordConfig.UserAgent); (Causes issues in .Net 4.6+)
|
//_gatewayClient.SetHeader("user-agent", DiscordConfig.UserAgent); (Causes issues in .Net 4.6+)
|
||||||
_webSocketClient.BinaryMessage += async (data, index, count) =>
|
WebSocketClient.BinaryMessage += async (data, index, count) =>
|
||||||
{
|
{
|
||||||
using (var compressed = new MemoryStream(data, index + 2, count - 2))
|
using (var compressed = new MemoryStream(data, index + 2, count - 2))
|
||||||
using (var decompressed = new MemoryStream())
|
using (var decompressed = new MemoryStream())
|
||||||
@@ -80,12 +80,12 @@ namespace Discord.Audio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
_webSocketClient.TextMessage += async text =>
|
WebSocketClient.TextMessage += async text =>
|
||||||
{
|
{
|
||||||
var msg = JsonConvert.DeserializeObject<SocketFrame>(text);
|
var msg = JsonConvert.DeserializeObject<SocketFrame>(text);
|
||||||
await _receivedEvent.InvokeAsync((VoiceOpCode)msg.Operation, msg.Payload).ConfigureAwait(false);
|
await _receivedEvent.InvokeAsync((VoiceOpCode)msg.Operation, msg.Payload).ConfigureAwait(false);
|
||||||
};
|
};
|
||||||
_webSocketClient.Closed += async ex =>
|
WebSocketClient.Closed += async ex =>
|
||||||
{
|
{
|
||||||
await DisconnectAsync().ConfigureAwait(false);
|
await DisconnectAsync().ConfigureAwait(false);
|
||||||
await _disconnectedEvent.InvokeAsync(ex).ConfigureAwait(false);
|
await _disconnectedEvent.InvokeAsync(ex).ConfigureAwait(false);
|
||||||
@@ -101,7 +101,7 @@ namespace Discord.Audio
|
|||||||
{
|
{
|
||||||
_connectCancelToken?.Dispose();
|
_connectCancelToken?.Dispose();
|
||||||
(_udp as IDisposable)?.Dispose();
|
(_udp as IDisposable)?.Dispose();
|
||||||
(_webSocketClient as IDisposable)?.Dispose();
|
(WebSocketClient as IDisposable)?.Dispose();
|
||||||
}
|
}
|
||||||
_isDisposed = true;
|
_isDisposed = true;
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ namespace Discord.Audio
|
|||||||
payload = new SocketFrame { Operation = (int)opCode, Payload = payload };
|
payload = new SocketFrame { Operation = (int)opCode, Payload = payload };
|
||||||
if (payload != null)
|
if (payload != null)
|
||||||
bytes = Encoding.UTF8.GetBytes(SerializeJson(payload));
|
bytes = Encoding.UTF8.GetBytes(SerializeJson(payload));
|
||||||
await _webSocketClient.SendAsync(bytes, 0, bytes.Length, true).ConfigureAwait(false);
|
await WebSocketClient.SendAsync(bytes, 0, bytes.Length, true).ConfigureAwait(false);
|
||||||
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
|
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
public async Task SendAsync(byte[] data, int bytes)
|
public async Task SendAsync(byte[] data, int bytes)
|
||||||
@@ -177,8 +177,8 @@ namespace Discord.Audio
|
|||||||
_connectCancelToken = new CancellationTokenSource();
|
_connectCancelToken = new CancellationTokenSource();
|
||||||
var cancelToken = _connectCancelToken.Token;
|
var cancelToken = _connectCancelToken.Token;
|
||||||
|
|
||||||
_webSocketClient.SetCancelToken(cancelToken);
|
WebSocketClient.SetCancelToken(cancelToken);
|
||||||
await _webSocketClient.ConnectAsync(url).ConfigureAwait(false);
|
await WebSocketClient.ConnectAsync(url).ConfigureAwait(false);
|
||||||
|
|
||||||
_udp.SetCancelToken(cancelToken);
|
_udp.SetCancelToken(cancelToken);
|
||||||
await _udp.StartAsync().ConfigureAwait(false);
|
await _udp.StartAsync().ConfigureAwait(false);
|
||||||
@@ -211,7 +211,7 @@ namespace Discord.Audio
|
|||||||
|
|
||||||
//Wait for tasks to complete
|
//Wait for tasks to complete
|
||||||
await _udp.StopAsync().ConfigureAwait(false);
|
await _udp.StopAsync().ConfigureAwait(false);
|
||||||
await _webSocketClient.DisconnectAsync().ConfigureAwait(false);
|
await WebSocketClient.DisconnectAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
ConnectionState = ConnectionState.Disconnected;
|
ConnectionState = ConnectionState.Disconnected;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user