public async Task <string> ConnectInternal(string emailOrUsername, string password, string token) { bool success = false; await Disconnect(); _blockEvent.Reset(); _disconnectToken = new CancellationTokenSource(); string url = (await _api.GetWebSocket()).Url; if (token != null) { try { //Login using cached token await _webSocket.ConnectAsync(url); if (_isDebugMode) { RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); } _http.Token = token; await _webSocket.Login(_http.Token); if (_isDebugMode) { RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket got token."); } success = true; } catch (InvalidOperationException) //Bad Token { if (_isDebugMode) { RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket had a bad token."); } if (password == null) //If we don't have an alternate login, throw this error { throw; } } } if (!success) { //Open websocket while we wait for login response Task socketTask = _webSocket.ConnectAsync(url); if (password != null) //Normal Login { var response = await _api.Login(emailOrUsername, password); if (_isDebugMode) { RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket got token."); } token = response.Token; } else //Anonymous login { var response = await _api.LoginAnonymous(emailOrUsername); if (_isDebugMode) { RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket generated anonymous token."); } token = response.Token; } _http.Token = token; //Wait for websocket to finish connecting, then send token await socketTask; if (_isDebugMode) { RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket connected."); } await _webSocket.Login(_http.Token); if (_isDebugMode) { RaiseOnDebugMessage(DebugMessageType.Connection, $"DataSocket logged in."); } success = true; } if (success) { if (_config.UseMessageQueue) { _mainTask = MessageQueueLoop(); } else { _mainTask = _disconnectToken.Wait(); } _mainTask = _mainTask.ContinueWith(async x => { await _webSocket.DisconnectAsync(); #if !DNXCORE50 if (_config.EnableVoice) { await _voiceWebSocket.DisconnectAsync(); } #endif //Clear send queue Message ignored; while (_pendingMessages.TryDequeue(out ignored)) { } _channels.Clear(); _messages.Clear(); _roles.Clear(); _servers.Clear(); _users.Clear(); _blockEvent.Set(); _mainTask = null; }).Unwrap(); _isConnected = true; } else { token = null; } return(token); }