Beispiel #1
0
        public async Task ProcessPaymentAchievementsAsync(AccountStatsSummary playerStats, Payment payment, CancellationToken cancellationToken)
        {
            var achievementTypes = await _context.AchievementTypes.Where(q => q.IsArchived == false && (q.CoinsSpentOnAvatarItems != null || q.CoinsSpentOnBooster != null)).ToListAsync(cancellationToken);

            foreach (var a in achievementTypes)
            {
                if (a.CoinsSpentOnAvatarItems != null && payment.ShopItem.TypeId == ShopItemTypeIds.AvatarItem && playerStats.CoinsSpentOnAvatarItems >= a.CoinsSpentOnAvatarItems)
                {
                    _context.Achievements.Add(new Achievement
                    {
                        AccountId         = playerStats.AccountId,
                        AchievementTypeId = a.Id,
                        AchieveDateTime   = DateTime.UtcNow
                    });
                }
                else if (a.CoinsSpentOnBooster != null && payment.ShopItem.TypeId == ShopItemTypeIds.Booster && playerStats.CoinsSpentOnBoosterItems >= a.CoinsSpentOnBooster)
                {
                    _context.Achievements.Add(new Achievement
                    {
                        AccountId         = playerStats.AccountId,
                        AchievementTypeId = a.Id,
                        AchieveDateTime   = DateTime.UtcNow
                    });
                }
            }
        }
Beispiel #2
0
        public async Task ProcessBattleAchievementsAsync(OneToOneBattle battle, AccountStatsSummary player1Stats, AccountStatsSummary player2Stats, CancellationToken cancellationToken)
        {
            var achievementTypes = await _context.AchievementTypes.AsNoTracking().Where(q => q.IsArchived == false).ToListAsync(cancellationToken);

            var achievements = await _context.Achievements.Where(q => q.IsArchived == false && (q.AccountId == battle.Player1Id || q.AccountId == battle.Player2Id)).ToListAsync(cancellationToken);

            var player1Achievements = achievements.Where(q => q.AccountId == battle.Player1Id)
                                      .ToDictionary(q => q.AchievementTypeId);

            var player2Achievements = achievements.Where(q => q.AccountId == battle.Player1Id)
                                      .ToDictionary(q => q.AchievementTypeId);

            // Winner
            foreach (var a in achievementTypes)
            {
                if (a.WinnedBattlesCount != null)
                {
                    ProcessWinnerAchievement(battle.Player1Id, player1Stats, player1Achievements, a);
                    ProcessWinnerAchievement(battle.Player2Id.Value, player2Stats, player2Achievements, a);
                }
                else if (a.AceWinCount != null)
                {
                    ProcessAceWinAchievement(battle.Player1Id, player1Stats, player1Achievements, a);
                    ProcessAceWinAchievement(battle.Player2Id.Value, player2Stats, player2Achievements, a);
                }
                else if (a.NumberOfTotalBattlesPlayed != null)
                {
                    ProcessTotalBattlesAchievement(battle.Player1Id, player1Stats, player1Achievements, a);
                    ProcessTotalBattlesAchievement(battle.Player2Id.Value, player2Stats, player2Achievements, a);
                }
            }

            await _context.SaveChangesAsync(cancellationToken);
        }
Beispiel #3
0
        public static AccountStatsSummaryViewModel Map(AccountStatsSummary stats,
                                                       List <AccountCategoryStatViewModel> categoryStats)
        {
            var model = AutoMapper.Mapper.Map <AccountStatsSummaryViewModel>(stats);

            model.Top5CategoryStats = categoryStats;

            return(model);
        }
Beispiel #4
0
        public static AccountStatsSummaryViewModel Map(AccountStatsSummary stats, Account account)
        {
            var model = AutoMapper.Mapper.Map <AccountStatsSummaryViewModel>(stats);

            model.FullName = !string.IsNullOrWhiteSpace(account.FirstName)
                    ? $"{account.FirstName} {account.LastName}"
                    : account.Nickname;

            return(model);
        }
Beispiel #5
0
        public async Task <ActionResult <ApiResultViewModel <AccountViewModel> > > Register(
            [FromBody] RegisterInputModel inputModel, CancellationToken cancellationToken)
        {
            var account = await _accountManager.FindByEmailAsync(inputModel.Email, cancellationToken);

            if (account != null)
            {
                return(BadRequest("invalid_email", "Email already exists"));
            }

            account = new Account
            {
                Email                = inputModel.Email,
                PasswordHash         = PasswordHash.CreateHash(inputModel.Password),
                StatusId             = AccountStatusIds.Active,
                Timezone             = "Asia/Tehran",
                ReceiveNotifications = true,
                SearchableByEmailAddressOrUsername = true,
                FriendsOnlyBattleInvitations       = false
            };
            account.Nickname         = account.Email.Substring(0, account.Email.IndexOf('@'));
            account.RegisterDateTime = DateTime.UtcNow;
            account.GenderId         = GenderIds.Male;
            account = await _accountManager.SaveAsync(account, cancellationToken);

            var accountStats = new AccountStatsSummary
            {
                AccountId = account.Id,
                Level     = 1
            };
            await _statsManager.SaveAsync(accountStats, cancellationToken);

            await SetDefaultAvatar(account, cancellationToken);

            await _dataContext.SaveChangesAsync(cancellationToken);

            var token = _tokenGenerator.GenerateToken(TimeSpan.FromDays(365),
                                                      new Claim(JwtRegisteredClaimNames.Jti, account.Id.ToString()),
                                                      new Claim(JwtRegisteredClaimNames.Sub, account.Email),
                                                      new Claim("Timezone", account.Timezone));

            var session = new Session
            {
                AccessToken      = token,
                AccountId        = account.Id,
                CreationDateTime = DateTime.UtcNow,
                StateId          = SessionStateIds.Created,
                SourceAppId      = AppIds.Game
            };

            await _sessionManager.SaveAsync(session, cancellationToken);

            return(CreatedData(RegisterViewModel.GetRegisterViewModel(AccountViewModel.Map(account),
                                                                      SessionViewModel.Map(session))));
        }
Beispiel #6
0
 public static ProfileViewModel Map(Account account, AccountStatsSummary stats)
 {
     return(new ProfileViewModel
     {
         AccountId = account.Id.ToString(),
         Name = account.Nickname,
         Level = stats?.Level,
         AvatarImageId = account.AvatarImageId,
         Rank = stats?.Rank ?? 0
     });
 }
Beispiel #7
0
 private void ProcessTotalBattlesAchievement(long playerId, AccountStatsSummary playerStats,
                                             Dictionary <long, Achievement> playerAchievements, AchievementType a)
 {
     if (!playerAchievements.ContainsKey(a.Id) && playerStats.TotalBattlesPlayed >= a.NumberOfTotalBattlesPlayed)
     {
         _context.Achievements.Add(new Achievement
         {
             AccountId         = playerId,
             AchievementTypeId = a.Id,
             AchieveDateTime   = DateTime.UtcNow
         });
     }
 }
Beispiel #8
0
 private void ProcessAceWinAchievement(long playerId, AccountStatsSummary playerStats,
                                       Dictionary <long, Achievement> playerAchievements, AchievementType a)
 {
     if (!playerAchievements.ContainsKey(a.Id) && playerStats.AceWinCount >= a.AceWinCount)
     {
         _context.Achievements.Add(new Achievement
         {
             AccountId         = playerId,
             AchievementTypeId = a.Id,
             AchieveDateTime   = DateTime.UtcNow
         });
     }
 }
Beispiel #9
0
        private void ProcessAceWinAchievement(long playerId, AccountStatsSummary playerStats,
                                              Dictionary <long, Achievement> playerAchievements, AchievementType a)
        {
            var option = new DbContextOptionsBuilder <DataContext>();

            option.UseSqlServer(_connectionStringOption.Mergen);
            using (DataContext dataContext = new DataContext(option.Options))
            {
                if (!playerAchievements.ContainsKey(a.Id) && playerStats.AceWinCount >= a.AceWinCount)
                {
                    dataContext.Achievements.Add(new Achievement
                    {
                        AccountId         = playerId,
                        AchievementTypeId = a.Id,
                        AchieveDateTime   = DateTime.UtcNow
                    });
                }
            }
        }
Beispiel #10
0
        public async Task ProcessSuccessfulBattleInvitationAchievements(BattleInvitation battleInvitation,
                                                                        AccountStatsSummary inviterPlayerStats, CancellationToken cancellationToken)
        {
            var achievementTypes = await _context.AchievementTypes.AsNoTracking().Where(q => q.IsArchived == false && q.NumberOfSuccessfulBattleInvitations != null).ToListAsync(cancellationToken);

            foreach (var a in achievementTypes)
            {
                if (inviterPlayerStats.SuccessfulBattleInvitationsCount >= a.NumberOfSuccessfulBattleInvitations)
                {
                    _context.Achievements.Add(new Achievement
                    {
                        AccountId         = battleInvitation.AccountId,
                        AchievementTypeId = a.Id,
                        AchieveDateTime   = DateTime.UtcNow
                    });
                }
            }

            await _context.SaveChangesAsync(cancellationToken);
        }
Beispiel #11
0
        public async Task <ActionResult <ApiResultViewModel <AccountViewModel> > > CreateAccount(
            [FromBody] AccountInputModel inputModel,
            CancellationToken cancellationToken)
        {
            var account = new Account();

            account.Email                 = inputModel.Email;
            account.PasswordHash          = PasswordHash.CreateHash(inputModel.Password);
            account.PhoneNumber           = inputModel.PhoneNumber;
            account.FirstName             = inputModel.FirstName;
            account.LastName              = inputModel.LastName;
            account.Nickname              = inputModel.Nickname;
            account.GenderId              = inputModel.GenderTypeId.ToInt();
            account.BirthDate             = inputModel.BirthDate;
            account.StatusId              = inputModel.StatusId.ToInt();
            account.StatusNote            = inputModel.StatusNote;
            account.IsEmailVerified       = inputModel.IsEmailVerified;
            account.IsPhoneNumberVerified = inputModel.IsPhoneNumberVerified;
            account.Timezone              = "Asia/Tehran";
            account.ReceiveNotifications  = true;
            account.SearchableByEmailAddressOrUsername = true;
            account.FriendsOnlyBattleInvitations       = false;
            account.RegisterDateTime = DateTime.UtcNow;

            using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                account = await _accountManager.SaveAsync(account, cancellationToken);

                await _accountManager.UpdateRolesAsync(account, inputModel.RoleIds.Select(rid => rid.ToLong()), cancellationToken);

                var accountStats = new AccountStatsSummary
                {
                    AccountId = account.Id
                };
                await _statsManager.SaveAsync(accountStats, cancellationToken);

                transaction.Complete();
            }

            return(OkData(AccountViewModel.Map(account)));
        }
Beispiel #12
0
        public async Task <ActionResult> AnswerGameQuestions([FromRoute] long gameId, [FromBody] AnswerGameQuestionsInputModel inputModel,
                                                             CancellationToken cancellationToken)
        {
            using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                var game = await _dataContext.Games
                           .Include(q => q.GameQuestions)
                           .ThenInclude(q => q.Question)
                           .ThenInclude(q => q.QuestionCategories)
                           .FirstOrDefaultAsync(q => q.Id == gameId, cancellationToken);

                #region Game Validation


                if (game == null)
                {
                    return(NotFound());
                }

                if (game.GameState == GameStateIds.Completed || game.GameState == GameStateIds.SelectCategory)
                {
                    return(BadRequest("invalid_gameState", "invalid_gameState"));
                }

                if (game.CurrentTurnPlayerId != AccountId)
                {
                    return(BadRequest("invalid_turn", "invalid_turn"));
                }

                var playerStat = await _dataContext.AccountStatsSummaries.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId, cancellationToken);

                if (playerStat == null)
                {
                    playerStat = new AccountStatsSummary
                    {
                        AccountId = game.CurrentTurnPlayerId.Value
                    };

                    _dataContext.AccountStatsSummaries.Add(playerStat);
                }

                if (inputModel.Answers.Count() != game.GameQuestions.Count)
                {
                    return(BadRequest("invalid_answersCount", "invalid_answersCount"));
                }

                #endregion


                var changedCategoryStats = new List <AccountCategoryStat>();

                foreach (var answer in inputModel.Answers)
                {
                    var gq = game.GameQuestions.FirstOrDefault(q => q.QuestionId == answer.QuestionId);

                    if (gq == null)
                    {
                        return(BadRequest("invalid_answers", "no such question in this game."));
                    }

                    var selectedAnswer = answer.SelectedAnswer;

                    if (game.GameState == GameStateIds.Player1AnswerQuestions)
                    {
                        if (gq.Player1SelectedAnswer.HasValue)
                        {
                            return(BadRequest("invalid_answers", "question already answered."));
                        }

                        gq.Player1SelectedAnswer = selectedAnswer;
                    }

                    else
                    {
                        if (gq.Player2SelectedAnswer.HasValue)
                        {
                            return(BadRequest("invalid_answers", "question already answered."));
                        }

                        gq.Player2SelectedAnswer = selectedAnswer;
                    }

                    var score = gq.Question.CorrectAnswerNumber == selectedAnswer ? 1 : 0;

                    switch (selectedAnswer)
                    {
                    case 1:
                        gq.Question.Answer1ChooseHistory++;
                        break;

                    case 2:
                        gq.Question.Answer2ChooseHistory++;
                        break;

                    case 3:
                        gq.Question.Answer3ChooseHistory++;
                        break;

                    case 4:
                        gq.Question.Answer4ChooseHistory++;
                        break;
                    }

                    // Process Category stats for player
                    foreach (var category in gq.Question.QuestionCategories)
                    {
                        var playerCategoryStat = await _dataContext.AccountCategoryStats.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId && q.CategoryId == category.Id, cancellationToken);

                        if (playerCategoryStat == null)
                        {
                            playerCategoryStat = new AccountCategoryStat
                            {
                                AccountId  = game.CurrentTurnPlayerId.Value,
                                CategoryId = category.CategoryId
                            };

                            _dataContext.AccountCategoryStats.Add(playerCategoryStat);
                            changedCategoryStats.Add(playerCategoryStat);
                        }

                        playerCategoryStat.TotalQuestionsCount += 1;
                        playerCategoryStat.CorrectAnswersCount += score;
                    }

                    if (answer.UsedAnswersHistoryHelper)
                    {
                        var accountCoin = await _dataContext.AccountItems.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId && q.ShopItemId == ShopItemTypeIds.Coin, cancellationToken);

                        if (accountCoin == null || accountCoin.Quantity < _gameSettingsOptions.AnswersHistoryHelperPrice)
                        {
                            // TODO: cheat detected
                            return(BadRequest("insufficient_funds", "insufficient funds to use this helper"));
                        }

                        accountCoin.Quantity -= _gameSettingsOptions.AnswersHistoryHelperPrice;
                    }

                    if (answer.UsedRemoveTwoAnswersHelper)
                    {
                        var accountCoin = await _dataContext.AccountItems.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId && q.ItemTypeId == ShopItemTypeIds.Coin, cancellationToken);

                        if (accountCoin == null || accountCoin.Quantity < _gameSettingsOptions.RemoveTwoAnswersHelperPrice)
                        {
                            // TODO: cheat detected
                            return(BadRequest("insufficient_funds", "insufficient funds to use this helper"));
                        }

                        accountCoin.Quantity -= _gameSettingsOptions.RemoveTwoAnswersHelperPrice;
                        playerStat.RemoveTwoAnswersHelperUsageCount += 1;
                    }

                    if (answer.UsedAskMergenHelper)
                    {
                        var accountCoin = await _dataContext.AccountItems.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId && q.ItemTypeId == ShopItemTypeIds.Coin, cancellationToken);

                        if (accountCoin == null || accountCoin.Quantity < _gameSettingsOptions.AskMergenHelperPrice)
                        {
                            // TODO: cheat detected
                            return(BadRequest("insufficient_funds", "insufficient funds to use this helper"));
                        }

                        accountCoin.Quantity -= _gameSettingsOptions.AskMergenHelperPrice;
                        playerStat.AskMergenHelperUsageCount += 1;
                    }

                    if (answer.UsedDoubleChanceHelper)
                    {
                        var accountCoin = await _dataContext.AccountItems.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId && q.ItemTypeId == ShopItemTypeIds.Coin, cancellationToken);

                        if (accountCoin == null || accountCoin.Quantity < _gameSettingsOptions.DoubleChanceHelperPrice)
                        {
                            // TODO: cheat detected
                            return(BadRequest("insufficient_funds", "insufficient funds to use this helper"));
                        }

                        accountCoin.Quantity -= _gameSettingsOptions.DoubleChanceHelperPrice;
                        playerStat.DoubleChanceHelperUsageCount += 1;
                    }

                    if (answer.TimeExtenderHelperUsageCount > 0)
                    {
                        var accountCoin = await _dataContext.AccountItems.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId && q.ItemTypeId == ShopItemTypeIds.Coin, cancellationToken);

                        if (accountCoin == null || accountCoin.Quantity < _gameSettingsOptions.TimeExtenderHelperPrice * answer.TimeExtenderHelperUsageCount)
                        {
                            // TODO: cheat detected
                            return(BadRequest("insufficient_funds", "insufficient funds to use this helper"));
                        }

                        accountCoin.Quantity -= _gameSettingsOptions.TimeExtenderHelperPrice * answer.TimeExtenderHelperUsageCount;
                        playerStat.TimeExtenderHelperUsageCount += 1;
                    }
                }

                await _achievementService.ProcessAnswerTimeAchievementsAsync(playerStat, changedCategoryStats, cancellationToken);

                var gameBattleId = game.BattleId;
                if (game.GameQuestions.All(q => q.Player1SelectedAnswer.HasValue && q.Player2SelectedAnswer.HasValue))
                {
                    game.GameState = GameStateIds.Completed;

                    var battle = await _dataContext.OneToOneBattles
                                 .Include(q => q.Games).ThenInclude(q => q.GameQuestions).ThenInclude(q => q.Question)
                                 .Include(q => q.Player1)
                                 .Include(q => q.Player2)
                                 .FirstOrDefaultAsync(q => q.Id == gameBattleId, cancellationToken);

                    if (battle.Games.Count != 6)
                    {
                        battle.Round += 1;
                    }



                    if (battle.Games.Count == 6 && battle.Games.All(q => q.GameState == GameStateIds.Completed))
                    {
                        // Battle Completed

                        battle.BattleStateId = BattleStateIds.Completed;
                        int player1CorrectAnswersCount = 0;
                        int player2CorrectAnswersCount = 0;
                        foreach (var battleGame in battle.Games)
                        {
                            player1CorrectAnswersCount += battleGame.GameQuestions.Sum(q => q.Player1SelectedAnswer == q.Question.CorrectAnswerNumber ? 1 : 0);

                            player2CorrectAnswersCount += battleGame.GameQuestions.Sum(q => q.Player2SelectedAnswer == q.Question.CorrectAnswerNumber ? 1 : 0);
                        }

                        battle.Player1CorrectAnswersCount = player1CorrectAnswersCount;
                        battle.Player2CorrectAnswersCount = player2CorrectAnswersCount;

                        if (player1CorrectAnswersCount > player2CorrectAnswersCount)
                        {
                            battle.WinnerPlayerId = battle.Player1Id;
                        }

                        else if (player2CorrectAnswersCount > player1CorrectAnswersCount)
                        {
                            battle.WinnerPlayerId = battle.Player2Id;
                        }

                        var playersStats = await _dataContext.AccountStatsSummaries
                                           .Where(q => q.AccountId == battle.Player1Id || q.AccountId == battle.Player2Id)
                                           .ToDictionaryAsync(q => q.AccountId, q => q, cancellationToken);

                        var player1Stats = playersStats[battle.Player1Id];
                        var player2Stats = playersStats[battle.Player2Id.Value];

                        player1Stats.TotalBattlesPlayed += 1;
                        player2Stats.TotalBattlesPlayed += 1;

                        if (battle.WinnerPlayerId == battle.Player1Id)
                        {
                            player1Stats.WinCount        += 1;
                            player2Stats.LoseCount       += 1;
                            player1Stats.LastPlayDateTime = DateTime.Now;
                            player2Stats.LastPlayDateTime = DateTime.Now;

                            if (await _battleManager.HasPlayedYesterday(player1Stats.AccountId, cancellationToken))
                            {
                                player1Stats.ContinuousActiveDaysCount += 1;
                            }

                            if (await _battleManager.HasPlayedYesterday(player2Stats.AccountId, cancellationToken))
                            {
                                player2Stats.ContinuousActiveDaysCount += 1;
                            }


                            if (player1CorrectAnswersCount == 18)
                            {
                                player1Stats.AceWinCount += 1;
                            }
                            // Experience for win
                            player1Stats.Score += player1CorrectAnswersCount + ExperienceBase * WinExperienceMultiplier;
                            player1Stats.Coins += player1CorrectAnswersCount + CoinBase * WinCoinMultiplier;

                            // Experience for lose
                            player2Stats.Score += player2CorrectAnswersCount + ExperienceBase * LoseExperienceMultiplier;
                            player2Stats.Coins += player2CorrectAnswersCount + CoinBase * LoseCoinMultiplier;
                        }
                        else if (battle.WinnerPlayerId == battle.Player2Id)
                        {
                            player1Stats.LoseCount += 1;
                            player2Stats.WinCount  += 1;

                            if (player2CorrectAnswersCount == 18)
                            {
                                player2Stats.AceWinCount += 1;
                            }

                            // Experience for win
                            player2Stats.Score += player2CorrectAnswersCount + ExperienceBase * WinExperienceMultiplier;
                            player2Stats.Coins += player2CorrectAnswersCount + CoinBase * WinCoinMultiplier;

                            // Experience for lose
                            player1Stats.Score += player1CorrectAnswersCount + ExperienceBase * LoseExperienceMultiplier;
                            player1Stats.Coins += player1CorrectAnswersCount + CoinBase * LoseCoinMultiplier;
                        }
                        else
                        {
                            // Exprience for draw (drop)

                            player1Stats.Score += player1CorrectAnswersCount + ExperienceBase * DrawExperienceMultiplier;
                            player2Stats.Score += player2CorrectAnswersCount + ExperienceBase * DrawExperienceMultiplier;
                        }

                        player1Stats.Level = _levelManager.GetLevel(player1Stats.Score)?.LevelNumber ?? 0;
                        player2Stats.Level = _levelManager.GetLevel(player2Stats.Score)?.LevelNumber ?? 0;

                        player1Stats.WinRatio = player1Stats.WinCount / (float)player1Stats.TotalBattlesPlayed;
                        player2Stats.WinRatio = player2Stats.WinCount / (float)player2Stats.TotalBattlesPlayed;

                        player1Stats.LoseRatio = player1Stats.LoseCount / (float)player1Stats.TotalBattlesPlayed;
                        player2Stats.LoseRatio = player2Stats.LoseCount / (float)player2Stats.TotalBattlesPlayed;

                        await _achievementService.ProcessBattleAchievementsAsync(battle, player1Stats, player2Stats,
                                                                                 cancellationToken);

                        var account = await _accountManager.GetAsync(game.CurrentTurnPlayerId.Value, cancellationToken);

                        var accountNotifId = game.CurrentTurnPlayerId == player1Stats.AccountId
                            ? player2Stats.AccountId
                            : player1Stats.AccountId;

                        await _notificationManager.SaveAsync(
                            new Core.Entities.Notification
                        {
                            AccountId          = accountNotifId,
                            Body               = $"Your battle Finish with{account.Email}",
                            NotificationTypeId = NotificationTypeIds.BattleCompleted,
                            Title              = "Battle Completed"
                        }, cancellationToken);

                        await _dataContext.SaveChangesAsync(cancellationToken);

                        // Calculate Sky
                        player1Stats.Sky = await CalculatePlayerSkyAsync(battle.Player1Id, cancellationToken);

                        player2Stats.Sky = await CalculatePlayerSkyAsync(battle.Player2Id.Value, cancellationToken);
                    }

                    else
                    {
                        var nextPlayer = game.CurrentTurnPlayerId == battle.Player1Id ? battle.Player1 : battle.Player2;
                        var newGame    = await _gamingService.CreateGameAsync(battle, nextPlayer.Id, cancellationToken);

                        battle.LastGame = newGame;
                    }
                }

                else
                {
                    var battle = await _dataContext.OneToOneBattles
                                 .Include(q => q.Player1)
                                 .Include(q => q.Player2)
                                 .FirstOrDefaultAsync(q => q.Id == gameBattleId, cancellationToken);

                    var nextPlayer = game.CurrentTurnPlayerId == battle.Player1Id ? battle.Player2 : battle.Player1;
                    game.CurrentTurnPlayerId = nextPlayer?.Id;
                    game.GameState           = game.CurrentTurnPlayerId == battle.Player1Id ? GameStateIds.Player1AnswerQuestions : GameStateIds.Player2AnswerQuestions;
                }

                await _dataContext.SaveChangesAsync(cancellationToken);

                transaction.Complete();
            }

            return(Ok());
        }
Beispiel #13
0
 public static StatsViewModel Map(AccountStatsSummary accountStatsSummary)
 {
     return(Mapper.Map <StatsViewModel>(accountStatsSummary));
 }
Beispiel #14
0
        public async Task ProcessAnswerTimeAchievementsAsync(AccountStatsSummary playerStat, List <AccountCategoryStat> changedCategoryStats, CancellationToken cancellationToken)
        {
            var achievementTypes = await _context.AchievementTypes.AsNoTracking().Where(q => q.IsArchived == false).ToListAsync(cancellationToken);

            foreach (var a in achievementTypes)
            {
                if (a.CorrectAnswersCountInCategory != null)
                {
                    var catStat = changedCategoryStats.FirstOrDefault(q => q.CategoryId == a.CategoryId);
                    if (catStat != null)
                    {
                        if (catStat.CorrectAnswersCount >= a.CorrectAnswersCountInCategory)
                        {
                            _context.Achievements.Add(new Achievement
                            {
                                AccountId         = playerStat.AccountId,
                                AchievementTypeId = a.Id,
                                AchieveDateTime   = DateTime.UtcNow,
                                TitleAchievement  = $"Category {catStat.Category.Title}"
                            });
                        }
                    }
                }
                if (a.RemoveTwoAnswersHelperUsageCount != null)
                {
                    if (playerStat.RemoveTwoAnswersHelperUsageCount >= a.RemoveTwoAnswersHelperUsageCount)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Facilitates Remove Two Answers {a.Title}"
                        });
                    }
                }
                if (a.AnswerHistoryHelperUsageCount != null)
                {
                    if (playerStat.AnswerHistoryHelperUsageCount >= a.AnswerHistoryHelperUsageCount)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Facilitates Answer History {a.Title}"
                        });
                    }
                }
                if (a.AskMergenHelperUsageCount != null)
                {
                    if (playerStat.AskMergenHelperUsageCount >= a.AskMergenHelperUsageCount)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Facilitates Ask Mergen Helper {a.Title}"
                        });
                    }
                }
                if (a.DoubleChanceHelperUsageCount != null)
                {
                    if (playerStat.DoubleChanceHelperUsageCount >= a.DoubleChanceHelperUsageCount)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Facilitates Double Chance Helper {a.Title}"
                        });
                    }
                }

                if (a.NumberOfContinuousDaysPlaying != null)
                {
                    //for (int i = 0; i < 30; i++)
                    //{
                    //    var continuous = await _context.OneToOneBattles.AnyAsync(x =>
                    //        x.IsArchived == false && x.StartDateTime == DateTime.Today.AddDays(-i), cancellationToken);

                    //    if (continuous)
                    //    {
                    //        playerStat.ContinuousActiveDaysCount += 1;
                    //        _context.AccountStatsSummaries.Update(playerStat);
                    //        await _context.SaveChangesAsync(cancellationToken);
                    //    }
                    //    else
                    //        break;


                    //}

                    if (a.NumberOfContinuousDaysPlaying == playerStat.ContinuousActiveDaysCount)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Continuous days play {a.Title}"
                        });
                    }
                }

                if (a.GiftedCoinsAmount != null)
                {
                    if (playerStat.GiftedCoins == a.GiftedCoinsAmount)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Generous {a.Title}"
                        });
                    }
                }

                if (a.NumberOfTotalBattlesPlayed != null)
                {
                    if (a.NumberOfTotalBattlesPlayed == playerStat.TotalBattlesPlayed)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Total Games {a.Title}"
                        });
                    }
                }

                if (a.NumberOfSuccessfulBattleInvitations != null)
                {
                    if (a.NumberOfSuccessfulBattleInvitations == playerStat.InvitedPlayersCount)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Invite {a.Title}"
                        });
                    }
                }

                if (a.CoinsSpentOnAvatarItems != null)
                {
                    if (a.CoinsSpentOnAvatarItems == playerStat.CoinsSpentOnAvatarItems)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Avatar {a.Title}"
                        });
                    }
                }

                if (a.CoinsSpentOnBooster != null)
                {
                    if (a.CoinsSpentOnBooster == playerStat.CoinsSpentOnBoosterItems)
                    {
                        _context.Achievements.Add(new Achievement
                        {
                            AccountId         = playerStat.AccountId,
                            AchievementTypeId = a.Id,
                            AchieveDateTime   = DateTime.UtcNow,
                            TitleAchievement  = $"Boost {a.Title}"
                        });
                    }
                }
            }

            await _context.SaveChangesAsync(cancellationToken);
        }
Beispiel #15
0
        public async Task Execute(IJobExecutionContext context)
        {
            var option = new DbContextOptionsBuilder <DataContext>();

            option.UseSqlServer(_connectionStringOption.Mergen);

            using (DataContext dataContext = new DataContext(option.Options))
            {
                var games = await dataContext.Games.Where(x => x.IsArchived == false && x.GameState == GameStateIds.Player2AnswerQuestions).ToListAsync();

                foreach (var game in games)
                {
                    var isBotPlayer = await dataContext.Accounts.FirstOrDefaultAsync(x => x.IsBot && x.Id == game.CurrentTurnPlayerId);

                    if (isBotPlayer is null)
                    {
                        continue;
                    }

                    var playerStat = await dataContext.AccountStatsSummaries.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId);

                    if (playerStat == null)
                    {
                        playerStat = new AccountStatsSummary
                        {
                            AccountId = game.CurrentTurnPlayerId.Value
                        };

                        dataContext.AccountStatsSummaries.Add(playerStat);
                    }

                    var gameQuestions = await dataContext.GameQuestions.Include(x => x.Question)
                                        .ThenInclude(x => x.QuestionCategories).Where(x => x.GameId == game.Id).ToListAsync();

                    if (gameQuestions.Count == 0)
                    {
                        continue;
                    }

                    var changedCategoryStats = new List <AccountCategoryStat>();

                    foreach (var gameQuestion in gameQuestions)
                    {
                        var randomAnswer = new Random().Next(1, 4);

                        gameQuestion.Player2SelectedAnswer = randomAnswer;

                        var score = gameQuestion.Question.CorrectAnswerNumber == randomAnswer ? 1 : 0;

                        switch (randomAnswer)
                        {
                        case 1:
                            gameQuestion.Question.Answer1ChooseHistory++;
                            break;

                        case 2:
                            gameQuestion.Question.Answer2ChooseHistory++;
                            break;

                        case 3:
                            gameQuestion.Question.Answer3ChooseHistory++;
                            break;

                        case 4:
                            gameQuestion.Question.Answer4ChooseHistory++;
                            break;
                        }

                        foreach (var category in gameQuestion.Question.QuestionCategories)
                        {
                            var playerCategoryStat = await dataContext.AccountCategoryStats.FirstOrDefaultAsync(q => q.AccountId == game.CurrentTurnPlayerId && q.CategoryId == category.Id);

                            if (playerCategoryStat == null)
                            {
                                playerCategoryStat = new AccountCategoryStat
                                {
                                    AccountId  = game.CurrentTurnPlayerId.Value,
                                    CategoryId = category.CategoryId
                                };

                                dataContext.AccountCategoryStats.Add(playerCategoryStat);
                                changedCategoryStats.Add(playerCategoryStat);
                            }

                            playerCategoryStat.TotalQuestionsCount += 1;
                            playerCategoryStat.CorrectAnswersCount += score;
                        }
                    }

                    var achievementTypess = await dataContext.AchievementTypes.AsNoTracking().Where(q => q.IsArchived == false).ToListAsync();

                    foreach (var a in achievementTypess)
                    {
                        if (a.CorrectAnswersCountInCategory != null)
                        {
                            var catStat = changedCategoryStats.FirstOrDefault(q => q.CategoryId == a.CategoryId);
                            if (catStat != null)
                            {
                                if (catStat.CorrectAnswersCount >= a.CorrectAnswersCountInCategory)
                                {
                                    dataContext.Achievements.Add(new Achievement
                                    {
                                        AccountId         = playerStat.AccountId,
                                        AchievementTypeId = a.Id,
                                        AchieveDateTime   = DateTime.UtcNow
                                    });
                                }
                            }
                        }
                    }

                    var gameBattleId = game.BattleId;

                    if (game.GameQuestions.All(q => q.Player1SelectedAnswer.HasValue && q.Player2SelectedAnswer.HasValue))
                    {
                        game.GameState = GameStateIds.Completed;

                        var battle = await dataContext.OneToOneBattles
                                     .Include(q => q.Games).ThenInclude(q => q.GameQuestions).ThenInclude(q => q.Question)
                                     .Include(q => q.Player1)
                                     .Include(q => q.Player2)
                                     .FirstOrDefaultAsync(q => q.Id == gameBattleId);

                        if (battle.Games.Count != 6)
                        {
                            battle.Round += 1;
                        }


                        if (battle.Games.Count == 6 && battle.Games.All(q => q.GameState == GameStateIds.Completed))
                        {
                            // Battle Completed

                            battle.BattleStateId = BattleStateIds.Completed;
                            int player1CorrectAnswersCount = 0;
                            int player2CorrectAnswersCount = 0;
                            foreach (var battleGame in battle.Games)
                            {
                                player1CorrectAnswersCount += battleGame.GameQuestions.Sum(q => q.Player1SelectedAnswer == q.Question.CorrectAnswerNumber ? 1 : 0);

                                player2CorrectAnswersCount += battleGame.GameQuestions.Sum(q => q.Player2SelectedAnswer == q.Question.CorrectAnswerNumber ? 1 : 0);
                            }

                            battle.Player1CorrectAnswersCount = player1CorrectAnswersCount;
                            battle.Player2CorrectAnswersCount = player2CorrectAnswersCount;

                            if (player1CorrectAnswersCount > player2CorrectAnswersCount)
                            {
                                battle.WinnerPlayerId = battle.Player1Id;
                            }
                            else if (player2CorrectAnswersCount > player1CorrectAnswersCount)
                            {
                                battle.WinnerPlayerId = battle.Player2Id;
                            }

                            var playersStats = await dataContext.AccountStatsSummaries
                                               .Where(q => q.AccountId == battle.Player1Id || q.AccountId == battle.Player2Id)
                                               .ToDictionaryAsync(q => q.AccountId, q => q);

                            var player1Stats = playersStats[battle.Player1Id];
                            var player2Stats = playersStats[battle.Player2Id.Value];

                            player1Stats.TotalBattlesPlayed += 1;
                            player2Stats.TotalBattlesPlayed += 1;

                            if (battle.WinnerPlayerId == battle.Player1Id)
                            {
                                player1Stats.WinCount  += 1;
                                player2Stats.LoseCount += 1;

                                if (player1CorrectAnswersCount == 15)
                                {
                                    player1Stats.AceWinCount += 1;
                                }

                                // Experience for win
                                player1Stats.Score += player1CorrectAnswersCount + ExperienceBase * WinExperienceMultiplier;
                                player1Stats.Coins += player1CorrectAnswersCount + CoinBase * WinCoinMultiplier;

                                // Experience for lose
                                player2Stats.Score += player2CorrectAnswersCount + ExperienceBase * LoseExperienceMultiplier;
                                player2Stats.Coins += player2CorrectAnswersCount + CoinBase * LoseCoinMultiplier;
                            }

                            else if (battle.WinnerPlayerId == battle.Player2Id)
                            {
                                player1Stats.LoseCount += 1;
                                player2Stats.WinCount  += 1;

                                if (player2CorrectAnswersCount == 15)
                                {
                                    player2Stats.AceWinCount += 1;
                                }

                                // Experience for win
                                player2Stats.Score += player2CorrectAnswersCount + ExperienceBase * WinExperienceMultiplier;
                                player2Stats.Coins += player2CorrectAnswersCount + CoinBase * WinCoinMultiplier;

                                // Experience for lose
                                player1Stats.Score += player1CorrectAnswersCount + ExperienceBase * LoseExperienceMultiplier;
                                player1Stats.Coins += player1CorrectAnswersCount + CoinBase * LoseCoinMultiplier;
                            }

                            else
                            {
                                // Exprience for draw (drop)

                                player1Stats.Score += player1CorrectAnswersCount + ExperienceBase * DrawExperienceMultiplier;
                                player2Stats.Score += player2CorrectAnswersCount + ExperienceBase * DrawExperienceMultiplier;
                            }

                            player1Stats.Level = _levelManager.GetLevel(player1Stats.Score)?.LevelNumber ?? 0;
                            player2Stats.Level = _levelManager.GetLevel(player2Stats.Score)?.LevelNumber ?? 0;

                            player1Stats.WinRatio = player1Stats.WinCount / (float)player1Stats.TotalBattlesPlayed;
                            player2Stats.WinRatio = player2Stats.WinCount / (float)player2Stats.TotalBattlesPlayed;

                            player1Stats.LoseRatio = player1Stats.LoseCount / (float)player1Stats.TotalBattlesPlayed;
                            player2Stats.LoseRatio = player2Stats.LoseCount / (float)player2Stats.TotalBattlesPlayed;

                            var achievementTypes = await dataContext.AchievementTypes.AsNoTracking().Where(q => q.IsArchived == false).ToListAsync();

                            var achievements = await dataContext.Achievements.Where(q => q.IsArchived == false && (q.AccountId == battle.Player1Id || q.AccountId == battle.Player2Id)).ToListAsync();

                            var player1Achievements = achievements.Where(q => q.AccountId == battle.Player1Id)
                                                      .ToDictionary(q => q.AchievementTypeId);

                            var player2Achievements = achievements.Where(q => q.AccountId == battle.Player1Id)
                                                      .ToDictionary(q => q.AchievementTypeId);

                            // Winner
                            foreach (var a in achievementTypes)
                            {
                                if (a.WinnedBattlesCount != null)
                                {
                                    ProcessWinnerAchievement(battle.Player1Id, player1Stats, player1Achievements, a);
                                    ProcessWinnerAchievement(battle.Player2Id.Value, player2Stats, player2Achievements, a);
                                }
                                else if (a.AceWinCount != null)
                                {
                                    ProcessAceWinAchievement(battle.Player1Id, player1Stats, player1Achievements, a);
                                    ProcessAceWinAchievement(battle.Player2Id.Value, player2Stats, player2Achievements, a);
                                }
                                else if (a.NumberOfTotalBattlesPlayed != null)
                                {
                                    ProcessTotalBattlesAchievement(battle.Player1Id, player1Stats, player1Achievements, a);
                                    ProcessTotalBattlesAchievement(battle.Player2Id.Value, player2Stats, player2Achievements, a);
                                }
                            }

                            await dataContext.SaveChangesAsync();

                            await dataContext.SaveChangesAsync();

                            // Calculate Sky
                            player1Stats.Sky = await CalculatePlayerSkyAsync(battle.Player1Id);

                            player2Stats.Sky = await CalculatePlayerSkyAsync(battle.Player2Id.Value);
                        }

                        else
                        {
                            var nextPlayer = game.CurrentTurnPlayerId == battle.Player1Id ? battle.Player1 : battle.Player2;
                            var newGame    = new Core.Entities.Game
                            {
                                CurrentTurnPlayerId = nextPlayer.Id,
                                GameState           = GameStateIds.SelectCategory,
                                Battle = battle
                            };

                            var randomCategoryIds = new HashSet <long>();
                            while (newGame.GameCategories.Count < 3)
                            {
                                var randomCategory = await dataContext.Categories.Where(q => q.IsArchived == false).OrderBy(q => Guid.NewGuid()).FirstOrDefaultAsync();

                                if (randomCategory != null && randomCategoryIds.Add(randomCategory.Id))
                                {
                                    newGame.GameCategories.Add(new GameCategory
                                    {
                                        CategoryId = randomCategory.Id
                                    });
                                }
                            }

                            battle.Games.Add(newGame);
                            dataContext.Games.Add(newGame);
                            battle.LastGame = newGame;
                        }
                    }

                    else
                    {
                        var battle = await dataContext.OneToOneBattles
                                     .Include(q => q.Player1)
                                     .Include(q => q.Player2)
                                     .FirstOrDefaultAsync(q => q.Id == gameBattleId);

                        var nextPlayer = game.CurrentTurnPlayerId == battle.Player1Id ? battle.Player2 : battle.Player1;
                        game.CurrentTurnPlayerId = nextPlayer?.Id;
                        game.GameState           = game.CurrentTurnPlayerId == battle.Player1Id ? GameStateIds.Player1AnswerQuestions : GameStateIds.Player2AnswerQuestions;
                    }

                    await dataContext.SaveChangesAsync();
                }
            }
        }