| @@ -35,7 +35,6 @@ namespace Discord.API | |||||
| protected bool _isDisposed; | protected bool _isDisposed; | ||||
| private CancellationTokenSource _loginCancelToken; | private CancellationTokenSource _loginCancelToken; | ||||
| private bool _fetchCurrentUser; | |||||
| public RetryMode DefaultRetryMode { get; } | public RetryMode DefaultRetryMode { get; } | ||||
| public string UserAgent { get; } | public string UserAgent { get; } | ||||
| @@ -45,18 +44,15 @@ namespace Discord.API | |||||
| public TokenType AuthTokenType { get; private set; } | public TokenType AuthTokenType { get; private set; } | ||||
| internal string AuthToken { get; private set; } | internal string AuthToken { get; private set; } | ||||
| internal IRestClient RestClient { get; private set; } | internal IRestClient RestClient { get; private set; } | ||||
| internal User CurrentUser { get; private set; } | |||||
| public ulong? CurrentUserId => CurrentUser?.Id; | |||||
| internal ulong? CurrentUserId { get; set;} | |||||
| 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) | |||||
| { | { | ||||
| 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() }; | ||||
| _fetchCurrentUser = fetchCurrentUser; | |||||
| RequestQueue = new RequestQueue(); | RequestQueue = new RequestQueue(); | ||||
| _stateLock = new SemaphoreSlim(1, 1); | _stateLock = new SemaphoreSlim(1, 1); | ||||
| @@ -126,9 +122,6 @@ namespace Discord.API | |||||
| AuthToken = token; | AuthToken = token; | ||||
| RestClient.SetHeader("authorization", GetPrefixedToken(AuthTokenType, AuthToken)); | RestClient.SetHeader("authorization", GetPrefixedToken(AuthTokenType, AuthToken)); | ||||
| if (_fetchCurrentUser) | |||||
| CurrentUser = await GetMyUserAsync(new RequestOptions { IgnoreState = true, RetryMode = RetryMode.AlwaysRetry }).ConfigureAwait(false); | |||||
| LoginState = LoginState.LoggedIn; | LoginState = LoginState.LoggedIn; | ||||
| } | } | ||||
| catch (Exception) | catch (Exception) | ||||
| @@ -162,7 +155,7 @@ namespace Discord.API | |||||
| await RequestQueue.SetCancelTokenAsync(CancellationToken.None).ConfigureAwait(false); | await RequestQueue.SetCancelTokenAsync(CancellationToken.None).ConfigureAwait(false); | ||||
| RestClient.SetCancelToken(CancellationToken.None); | RestClient.SetCancelToken(CancellationToken.None); | ||||
| CurrentUser = null; | |||||
| CurrentUserId = null; | |||||
| LoginState = LoginState.LoggedOut; | LoginState = LoginState.LoggedOut; | ||||
| } | } | ||||
| @@ -949,7 +942,7 @@ namespace Discord.API | |||||
| Preconditions.NotNull(args, nameof(args)); | Preconditions.NotNull(args, nameof(args)); | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| bool isCurrentUser = userId == CurrentUser.Id; | |||||
| bool isCurrentUser = userId == CurrentUserId; | |||||
| if (isCurrentUser && args.Nickname.IsSpecified) | if (isCurrentUser && args.Nickname.IsSpecified) | ||||
| { | { | ||||
| @@ -17,10 +17,11 @@ namespace Discord.Rest | |||||
| private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config) | private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config) | ||||
| => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent); | => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent); | ||||
| protected override Task OnLoginAsync(TokenType tokenType, string token) | |||||
| protected override async Task OnLoginAsync(TokenType tokenType, string token) | |||||
| { | { | ||||
| base.CurrentUser = RestSelfUser.Create(this, ApiClient.CurrentUser); | |||||
| return Task.Delay(0); | |||||
| var user = await ApiClient.GetMyUserAsync(new RequestOptions { RetryMode = RetryMode.AlwaysRetry }).ConfigureAwait(false); | |||||
| ApiClient.CurrentUserId = user.Id; | |||||
| base.CurrentUser = RestSelfUser.Create(this, user); | |||||
| } | } | ||||
| protected override Task OnLogoutAsync() | protected override Task OnLogoutAsync() | ||||
| { | { | ||||
| @@ -69,7 +69,7 @@ namespace Discord.API | |||||
| public DiscordRpcApiClient(string clientId, string userAgent, string origin, RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, | public DiscordRpcApiClient(string clientId, string userAgent, string origin, RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, | ||||
| RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null) | RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null) | ||||
| : base(restClientProvider, userAgent, defaultRetryMode, serializer, false) | |||||
| : base(restClientProvider, userAgent, defaultRetryMode, serializer) | |||||
| { | { | ||||
| _connectionLock = new SemaphoreSlim(1, 1); | _connectionLock = new SemaphoreSlim(1, 1); | ||||
| _clientId = clientId; | _clientId = clientId; | ||||
| @@ -435,6 +435,7 @@ namespace Discord.Rpc | |||||
| { | { | ||||
| var response = await ApiClient.SendAuthenticateAsync(options).ConfigureAwait(false); | var response = await ApiClient.SendAuthenticateAsync(options).ConfigureAwait(false); | ||||
| CurrentUser = RestSelfUser.Create(this, response.User); | CurrentUser = RestSelfUser.Create(this, response.User); | ||||
| ApiClient.CurrentUserId = CurrentUser.Id; | |||||
| ApplicationInfo = RestApplication.Create(this, response.Application); | ApplicationInfo = RestApplication.Create(this, response.Application); | ||||
| Scopes = response.Scopes; | Scopes = response.Scopes; | ||||
| TokenExpiresAt = response.Expires; | TokenExpiresAt = response.Expires; | ||||
| @@ -64,7 +64,7 @@ namespace Discord.WebSocket | |||||
| _shardIdsToIndex.Add(_shardIds[i], i); | _shardIdsToIndex.Add(_shardIds[i], i); | ||||
| var newConfig = config.Clone(); | var newConfig = config.Clone(); | ||||
| newConfig.ShardId = _shardIds[i]; | newConfig.ShardId = _shardIds[i]; | ||||
| _shards[i] = new DiscordSocketClient(newConfig, _connectionGroupLock); | |||||
| _shards[i] = new DiscordSocketClient(newConfig, _connectionGroupLock, i != 0 ? _shards[0] : null); | |||||
| RegisterEvents(_shards[i]); | RegisterEvents(_shards[i]); | ||||
| } | } | ||||
| } | } | ||||
| @@ -86,7 +86,7 @@ namespace Discord.WebSocket | |||||
| var newConfig = _baseConfig.Clone(); | var newConfig = _baseConfig.Clone(); | ||||
| newConfig.ShardId = _shardIds[i]; | newConfig.ShardId = _shardIds[i]; | ||||
| newConfig.TotalShards = _totalShards; | newConfig.TotalShards = _totalShards; | ||||
| _shards[i] = new DiscordSocketClient(newConfig, _connectionGroupLock); | |||||
| _shards[i] = new DiscordSocketClient(newConfig, _connectionGroupLock, i != 0 ? _shards[0] : null); | |||||
| RegisterEvents(_shards[i]); | RegisterEvents(_shards[i]); | ||||
| } | } | ||||
| } | } | ||||
| @@ -35,7 +35,7 @@ namespace Discord.API | |||||
| public DiscordSocketApiClient(RestClientProvider restClientProvider, string userAgent, WebSocketProvider webSocketProvider, | public DiscordSocketApiClient(RestClientProvider restClientProvider, string userAgent, WebSocketProvider webSocketProvider, | ||||
| 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) | |||||
| { | { | ||||
| WebSocketClient = webSocketProvider(); | WebSocketClient = webSocketProvider(); | ||||
| //WebSocketClient.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+) | ||||
| @@ -27,6 +27,7 @@ namespace Discord.WebSocket | |||||
| private readonly Logger _gatewayLogger; | private readonly Logger _gatewayLogger; | ||||
| private readonly JsonSerializer _serializer; | private readonly JsonSerializer _serializer; | ||||
| private readonly SemaphoreSlim _connectionGroupLock; | private readonly SemaphoreSlim _connectionGroupLock; | ||||
| private readonly DiscordSocketClient _parentClient; | |||||
| private string _sessionId; | private string _sessionId; | ||||
| private int _lastSeq; | private int _lastSeq; | ||||
| @@ -71,9 +72,9 @@ namespace Discord.WebSocket | |||||
| /// <summary> Creates a new REST/WebSocket discord client. </summary> | /// <summary> Creates a new REST/WebSocket discord client. </summary> | ||||
| public DiscordSocketClient() : this(new DiscordSocketConfig()) { } | public DiscordSocketClient() : this(new DiscordSocketConfig()) { } | ||||
| /// <summary> Creates a new REST/WebSocket discord client. </summary> | /// <summary> Creates a new REST/WebSocket discord client. </summary> | ||||
| public DiscordSocketClient(DiscordSocketConfig config) : this(config, CreateApiClient(config), null) { } | |||||
| internal DiscordSocketClient(DiscordSocketConfig config, SemaphoreSlim groupLock) : this(config, CreateApiClient(config), groupLock) { } | |||||
| private DiscordSocketClient(DiscordSocketConfig config, API.DiscordSocketApiClient client, SemaphoreSlim groupLock) | |||||
| public DiscordSocketClient(DiscordSocketConfig config) : this(config, CreateApiClient(config), null, null) { } | |||||
| internal DiscordSocketClient(DiscordSocketConfig config, SemaphoreSlim groupLock, DiscordSocketClient parentClient) : this(config, CreateApiClient(config), groupLock, parentClient) { } | |||||
| private DiscordSocketClient(DiscordSocketConfig config, API.DiscordSocketApiClient client, SemaphoreSlim groupLock, DiscordSocketClient parentClient) | |||||
| : base(config, client) | : base(config, client) | ||||
| { | { | ||||
| ShardId = config.ShardId ?? 0; | ShardId = config.ShardId ?? 0; | ||||
| @@ -90,6 +91,7 @@ namespace Discord.WebSocket | |||||
| _nextAudioId = 1; | _nextAudioId = 1; | ||||
| _gatewayLogger = LogManager.CreateLogger(ShardId == 0 && TotalShards == 1 ? "Gateway" : "Shard #" + ShardId); | _gatewayLogger = LogManager.CreateLogger(ShardId == 0 && TotalShards == 1 ? "Gateway" : "Shard #" + ShardId); | ||||
| _connectionGroupLock = groupLock; | _connectionGroupLock = groupLock; | ||||
| _parentClient = parentClient; | |||||
| _serializer = new JsonSerializer { ContractResolver = new DiscordContractResolver() }; | _serializer = new JsonSerializer { ContractResolver = new DiscordContractResolver() }; | ||||
| _serializer.Error += (s, e) => | _serializer.Error += (s, e) => | ||||
| @@ -134,8 +136,13 @@ namespace Discord.WebSocket | |||||
| protected override async Task OnLoginAsync(TokenType tokenType, string token) | protected override async Task OnLoginAsync(TokenType tokenType, string token) | ||||
| { | { | ||||
| var voiceRegions = await ApiClient.GetVoiceRegionsAsync(new RequestOptions { IgnoreState = true, RetryMode = RetryMode.AlwaysRetry }).ConfigureAwait(false); | |||||
| _voiceRegions = voiceRegions.Select(x => RestVoiceRegion.Create(this, x)).ToImmutableDictionary(x => x.Id); | |||||
| if (_parentClient == null) | |||||
| { | |||||
| var voiceRegions = await ApiClient.GetVoiceRegionsAsync(new RequestOptions { IgnoreState = true, RetryMode = RetryMode.AlwaysRetry }).ConfigureAwait(false); | |||||
| _voiceRegions = voiceRegions.Select(x => RestVoiceRegion.Create(this, x)).ToImmutableDictionary(x => x.Id); | |||||
| } | |||||
| else | |||||
| _voiceRegions = _parentClient._voiceRegions; | |||||
| } | } | ||||
| protected override async Task OnLogoutAsync() | protected override async Task OnLogoutAsync() | ||||
| { | { | ||||
| @@ -603,6 +610,7 @@ namespace Discord.WebSocket | |||||
| var state = new ClientState(data.Guilds.Length, data.PrivateChannels.Length); | var state = new ClientState(data.Guilds.Length, data.PrivateChannels.Length); | ||||
| var currentUser = SocketSelfUser.Create(this, state, data.User); | var currentUser = SocketSelfUser.Create(this, state, data.User); | ||||
| ApiClient.CurrentUserId = currentUser.Id; | |||||
| int unavailableGuilds = 0; | int unavailableGuilds = 0; | ||||
| for (int i = 0; i < data.Guilds.Length; i++) | for (int i = 0; i < data.Guilds.Length; i++) | ||||
| { | { | ||||