Call /gateway on reconnect, use /login to verify cached tokens
This commit is contained in:
@@ -159,8 +159,8 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Connects to the Discord server with the provided email and password. </summary>
|
/// <summary> Connects to the Discord server with the provided email and password. </summary>
|
||||||
/// <returns> Returns a token that can be optionally stored for future connections. </returns>
|
/// <returns> Returns a token that can be optionally stored to speed up future connections. </returns>
|
||||||
public async Task<string> Connect(string email, string password)
|
public async Task<string> Connect(string email, string password, string token = null)
|
||||||
{
|
{
|
||||||
if (email == null) throw new ArgumentNullException(email);
|
if (email == null) throw new ArgumentNullException(email);
|
||||||
if (password == null) throw new ArgumentNullException(password);
|
if (password == null) throw new ArgumentNullException(password);
|
||||||
@@ -168,13 +168,13 @@ namespace Discord
|
|||||||
await BeginConnect(email, password, null).ConfigureAwait(false);
|
await BeginConnect(email, password, null).ConfigureAwait(false);
|
||||||
return ClientAPI.Token;
|
return ClientAPI.Token;
|
||||||
}
|
}
|
||||||
/// <summary> Connects to the Discord server with the provided token. </summary>
|
/*/// <summary> Connects to the Discord server with the provided token. </summary>
|
||||||
public async Task Connect(string token)
|
public async Task Connect(string token)
|
||||||
{
|
{
|
||||||
if (token == null) throw new ArgumentNullException(token);
|
if (token == null) throw new ArgumentNullException(token);
|
||||||
|
|
||||||
await BeginConnect(null, null, token).ConfigureAwait(false);
|
await BeginConnect(null, null, token).ConfigureAwait(false);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private async Task BeginConnect(string email, string password, string token = null)
|
private async Task BeginConnect(string email, string password, string token = null)
|
||||||
{
|
{
|
||||||
@@ -222,65 +222,40 @@ namespace Discord
|
|||||||
throw;
|
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;
|
string tokenPath = null, oldToken = null;
|
||||||
while (true)
|
byte[] cacheKey = null;
|
||||||
|
|
||||||
|
//Get Token
|
||||||
|
if (token == null && Config.CacheToken)
|
||||||
{
|
{
|
||||||
//Get Token
|
Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(password,
|
||||||
if (token == null)
|
new byte[] { 0x5A, 0x2A, 0xF8, 0xCF, 0x78, 0xD3, 0x7D, 0x0D });
|
||||||
{
|
cacheKey = deriveBytes.GetBytes(16);
|
||||||
if (useCache)
|
|
||||||
{
|
|
||||||
Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(password,
|
|
||||||
new byte[] { 0x5A, 0x2A, 0xF8, 0xCF, 0x78, 0xD3, 0x7D, 0x0D });
|
|
||||||
byte[] key = deriveBytes.GetBytes(16);
|
|
||||||
|
|
||||||
string tokenPath = GetTokenCachePath(email);
|
tokenPath = GetTokenCachePath(email);
|
||||||
token = LoadToken(tokenPath, key);
|
oldToken = LoadToken(tokenPath, cacheKey);
|
||||||
if (token == null)
|
ClientAPI.Token = oldToken;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientAPI.Token = token;
|
|
||||||
GatewaySocket.Token = token;
|
|
||||||
GatewaySocket.SessionId = null;
|
|
||||||
|
|
||||||
//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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ClientAPI.Token = token;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
ClientAPI.Token = token;
|
||||||
|
|
||||||
|
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()
|
private void EndConnect()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Discord.API.Client;
|
using Discord.API.Client;
|
||||||
using Discord.API.Client.GatewaySocket;
|
using Discord.API.Client.GatewaySocket;
|
||||||
|
using Discord.API.Client.Rest;
|
||||||
using Discord.Logging;
|
using Discord.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
@@ -34,6 +35,11 @@ namespace Discord.Net.WebSockets
|
|||||||
|
|
||||||
public async Task Connect()
|
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);
|
await BeginConnect().ConfigureAwait(false);
|
||||||
if (SessionId == null)
|
if (SessionId == null)
|
||||||
SendIdentify(Token);
|
SendIdentify(Token);
|
||||||
@@ -49,6 +55,7 @@ namespace Discord.Net.WebSockets
|
|||||||
await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false);
|
await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||||
else
|
else
|
||||||
await Task.Delay(_client.Config.FailedReconnectDelay, cancelToken).ConfigureAwait(false);
|
await Task.Delay(_client.Config.FailedReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||||
|
|
||||||
while (!cancelToken.IsCancellationRequested)
|
while (!cancelToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user