private void OnOpen(IWebSocketConnection socket) { socket.OnMessage += async s => { if (!_users.TryGetValue(socket, out var user)) { if (_crypto.TryDecrypt(s, out var decryptResult) && _passwords.Select(x => x.User).Contains(decryptResult.password.User)) { var item = _userFactory.Create(socket, decryptResult.password); _users.TryAdd(socket, item); socket.OnClose += () => { _users.TryRemove(socket, out _); }; item.OnDisconnected += RemoveUser; await item.Write(_messageFactory.CreateLoginApiAccepted(), false); await _logManager.LogInformation( $"User {decryptResult.password.User} logged in."); } else { RemoveFromTimeout(); await socket.Send(_messageFactory.CreateLoginApiRejected()); socket.Close(); } } else { var data = _crypto.Decrypt(s, user.Password.ToString()); if (string.IsNullOrEmpty(data)) { return; } ApiMessage message; try { message = JsonSerializer.Deserialize <ApiMessage>(data); } catch { _logger.LogWarning("ImpostorHQ Danger: user {Address} is sending malformed API messages.", socket.ConnectionInfo.ClientIpAddress); await user.Kick(); RemoveUser(); return; } var(success, exception) = await user.HandleMessage(message); if (!success) { _logger.LogWarning("ImpostorHQ Danger: user {Address} tried to execute an invalid operation.", socket.ConnectionInfo.ClientIpAddress); await user.Kick(); RemoveUser(); await _logManager.LogError( $"User {socket.ConnectionInfo.ClientIpAddress} created error on HandleMessage.", exception); } } }; void RemoveFromTimeout() { _timeouts.TryRemove(socket, out _); } void RemoveUser() { _users.TryRemove(socket, out _); socket.Close(); } }