diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 535a3eff9..0074e89f8 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -159,8 +159,8 @@ namespace Discord } /// Connects to the Discord server with the provided email and password. - /// Returns a token that can be optionally stored for future connections. - public async Task Connect(string email, string password) + /// Returns a token that can be optionally stored to speed up future connections. + public async Task Connect(string email, string password, string token = null) { if (email == null) throw new ArgumentNullException(email); if (password == null) throw new ArgumentNullException(password); @@ -168,13 +168,13 @@ namespace Discord await BeginConnect(email, password, null).ConfigureAwait(false); return ClientAPI.Token; } - /// Connects to the Discord server with the provided token. + /*/// Connects to the Discord server with the provided token. public async Task Connect(string token) { if (token == null) throw new ArgumentNullException(token); await BeginConnect(null, null, token).ConfigureAwait(false); - } + }*/ private async Task BeginConnect(string email, string password, string token = null) { @@ -222,65 +222,40 @@ namespace Discord throw; } } - private async Task Login(string email, string password, string token) + private async Task Login(string email, string password, string token = null) { - bool useCache = Config.CacheToken; - while (true) - { - //Get Token - if (token == null) - { - if (useCache) - { - Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(password, - new byte[] { 0x5A, 0x2A, 0xF8, 0xCF, 0x78, 0xD3, 0x7D, 0x0D }); - byte[] key = deriveBytes.GetBytes(16); + string tokenPath = null, oldToken = null; + byte[] cacheKey = null; - string tokenPath = GetTokenCachePath(email); - token = LoadToken(tokenPath, key); - if (token == null) - { - var request = new LoginRequest() { Email = email, Password = password }; - var response = await ClientAPI.Send(request).ConfigureAwait(false); - token = response.Token; - SaveToken(tokenPath, key, token); - useCache = false; - } - } - else - { - var request = new LoginRequest() { Email = email, Password = password }; - var response = await ClientAPI.Send(request).ConfigureAwait(false); - token = response.Token; - } - } + //Get Token + if (token == null && Config.CacheToken) + { + Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(password, + new byte[] { 0x5A, 0x2A, 0xF8, 0xCF, 0x78, 0xD3, 0x7D, 0x0D }); + cacheKey = deriveBytes.GetBytes(16); + tokenPath = GetTokenCachePath(email); + oldToken = LoadToken(tokenPath, cacheKey); + ClientAPI.Token = oldToken; + } + else ClientAPI.Token = token; - GatewaySocket.Token = token; - GatewaySocket.SessionId = null; + + var request = new LoginRequest() { Email = email, Password = password }; + var response = await ClientAPI.Send(request).ConfigureAwait(false); + token = response.Token; + if (Config.CacheToken && token != oldToken) + SaveToken(tokenPath, cacheKey, token); - //Get gateway and check token - try - { - var gatewayResponse = await ClientAPI.Send(new GatewayRequest()).ConfigureAwait(false); - var gateway = gatewayResponse.Url; - GatewaySocket.Host = gateway; - if (Config.LogLevel >= LogSeverity.Verbose) - Logger.Verbose($"Login successful, gateway: {gateway}"); - } - catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized && useCache) - { - useCache = false; //Cached token is bad, retry without cache - token = null; - continue; - } + ClientAPI.Token = token; - //Cache other stuff - var regionsResponse = (await ClientAPI.Send(new GetVoiceRegionsRequest()).ConfigureAwait(false)); - _regions = regionsResponse.Select(x => new Region(x.Id, x.Name, x.Hostname, x.Port, x.Vip)) - .ToDictionary(x => x.Id); - break; - } + GatewaySocket.Token = token; + GatewaySocket.SessionId = null; + + //Cache other stuff + var regionsResponse = (await ClientAPI.Send(new GetVoiceRegionsRequest()).ConfigureAwait(false)); + _regions = regionsResponse.Select(x => new Region(x.Id, x.Name, x.Hostname, x.Port, x.Vip)) + .ToDictionary(x => x.Id); } private void EndConnect() { diff --git a/src/Discord.Net/Net/WebSockets/GatewaySocket.cs b/src/Discord.Net/Net/WebSockets/GatewaySocket.cs index 22ae0af57..bd2a8ab6a 100644 --- a/src/Discord.Net/Net/WebSockets/GatewaySocket.cs +++ b/src/Discord.Net/Net/WebSockets/GatewaySocket.cs @@ -1,5 +1,6 @@ using Discord.API.Client; using Discord.API.Client.GatewaySocket; +using Discord.API.Client.Rest; using Discord.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -34,6 +35,11 @@ namespace Discord.Net.WebSockets public async Task Connect() { + var gatewayResponse = await _client.ClientAPI.Send(new GatewayRequest()).ConfigureAwait(false); + Host = gatewayResponse.Url; + if (Logger.Level >= LogSeverity.Verbose) + Logger.Verbose($"Login successful, gateway: {gatewayResponse.Url}"); + await BeginConnect().ConfigureAwait(false); if (SessionId == null) SendIdentify(Token); @@ -49,6 +55,7 @@ namespace Discord.Net.WebSockets await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false); else await Task.Delay(_client.Config.FailedReconnectDelay, cancelToken).ConfigureAwait(false); + while (!cancelToken.IsCancellationRequested) { try