public async Task AddUserToQueue(UserInfo newUser, int wordsCountFilter, bool isGameWithFriend = false, string friendsGroupId = null) { if (wordsCountFilter <= 0) { throw new ArgumentException(nameof(wordsCountFilter)); } if (isGameWithFriend && string.IsNullOrEmpty(friendsGroupId)) { throw new ArgumentException(nameof(friendsGroupId)); } if (!newUser.IsBot && !isGameWithFriend) { DelayBotTimer(newUser.GameLevel, wordsCountFilter); } if (userGroupDictionary.ContainsKey(newUser.UserId)) { RemoveUser(newUser.UserId); } bool isConnectedToExistingGroup = false; IUserGroup existingGroup = null; var newUserFilterKey = new UserFilterKey(newUser.GameLevel, wordsCountFilter); if (isGameWithFriend) { friendsRoomsDictionary.TryGetValue(friendsGroupId, out existingGroup); } else { if (waitingUsers.TryRemove(newUserFilterKey, out existingGroup)) { if (existingGroup != null && existingGroup.IsEmpty()) { existingGroup = null; } } } if (existingGroup != null) { await existingGroup.ConnectUser(newUser); if (!newUser.IsBot) { userGroupDictionary.TryAdd(newUser.UserId, existingGroup); userAddedToGroup.OnNext(newUser.UserId); } groupFulledSubject.OnNext(existingGroup); var gameProvider = (IGameProvider)serviceProvider.GetService(typeof(IGameProvider)); var users = existingGroup.GetUsers(); try { await gameProvider.StartGame(users[0], users[1], existingGroup.GetGroupId(), users[0].GameLevel, newUser.IsBot, wordsCountFilter); existingGroup.GameProvider = gameProvider; gameStarted.OnNext(gameProvider); } catch (Exception ex) { // TODO: Log error failedToLoadGameSubject.OnNext(existingGroup); return; } isConnectedToExistingGroup = true; } if (!isConnectedToExistingGroup && !newUser.IsBot) { var newGroup = serviceProvider.GetService <IUserGroup>(); await newGroup.EstablishConnection(newUser); userGroupDictionary.TryAdd(newUser.UserId, newGroup); if (!isGameWithFriend) { waitingUsers.TryAdd(newUserFilterKey, newGroup); } else { newGroup.SetUpFriendToConnectGroupId(friendsGroupId); friendsRoomsDictionary.TryAdd(friendsGroupId, newGroup); } userAddedToGroup.OnNext(newUser.UserId); if (!isGameWithFriend) { SetUpBotTimer(newUser.GameLevel, wordsCountFilter); } } }