예제 #1
0
 public bool TryGetLastOperationCheck(IUser user, out BdsmTraitOperationCheck lastCheck)
 => Cache.TryGetValue(ToLastOperationCheckKey(user), out lastCheck);
예제 #2
0
 private void SetLastOperationCheck(IUser user, BdsmTraitOperationCheck lastCheck)
 => Cache.Set(ToLastOperationCheckKey(user), lastCheck);
예제 #3
0
        /// <summary>
        /// Check based on BDSM results.
        /// This check probabilistically prevents sub users from whipping dom users.
        /// </summary>
        /// <param name="user">Initiator (whipping user)</param>
        /// <param name="target">Target (user to be whipped)</param>
        /// <returns>Detailed results of the check.</returns>
        public async Task <BdsmTraitOperationCheck> CheckDomSubOperationAsync(IUser user, IUser target)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            using var dbContext = DatabaseFactory.Create();

            var userDb = await dbContext.GetOrCreateUserEntityAsync(user);

            var targetDb = await dbContext.GetOrCreateUserEntityAsync(target);

            var check = new BdsmTraitOperationCheck(CheckTranslations, userDb.Gender, targetDb.Gender)
            {
                UserDisplayName   = Format.Sanitize(await UsersService.GetDisplayNameAsync(user)),
                TargetDisplayName = Format.Sanitize(await UsersService.GetDisplayNameAsync(target))
            };

            SetLastOperationCheck(user, check);

            if (user.Equals(target))
            {
                check.Result = BdsmTraitOperationCheckResult.Self;
                return(check);
            }

            if (!userDb.HasGivenConsentTo(CommandConsent.BdsmImageCommands))
            {
                check.Result = BdsmTraitOperationCheckResult.UserDidNotConsent;
                return(check);
            }

            if (!targetDb.HasGivenConsentTo(CommandConsent.BdsmImageCommands))
            {
                check.Result = BdsmTraitOperationCheckResult.TargetDidNotConsent;
                return(check);
            }

            if (!await TestExists(user))
            {
                check.Result = BdsmTraitOperationCheckResult.UserHasNoTest;
                return(check);
            }

            if (!await TestExists(target))
            {
                check.Result = BdsmTraitOperationCheckResult.TargetHasNoTest;
                return(check);
            }

            var userPoints = await dbContext.DailyUsersActivities.AsQueryable()
                             .Where(a => a.UserId == user.Id)
                             .SumAsync(a => a.Points);

            if (userPoints < 0)
            {
                check.Result = BdsmTraitOperationCheckResult.UserNegativePoints;
                return(check);
            }

            var userDominance = await GetTraitScore(user, BdsmTrait.Dominant);

            var userSubmissiveness = await GetTraitScore(user, BdsmTrait.Submissive);

            var targetDominance = await GetTraitScore(target, BdsmTrait.Dominant);

            var targetSubmissiveness = await GetTraitScore(target, BdsmTrait.Submissive);

            check.UserDominance        = userDominance.ToIntPercentage();
            check.UserSubmissiveness   = userSubmissiveness.ToIntPercentage();
            check.TargetDominance      = targetDominance.ToIntPercentage();
            check.TargetSubmissiveness = targetSubmissiveness.ToIntPercentage();

            var score = 0.0;

            score += userDominance * targetSubmissiveness;
            score -= targetDominance * userSubmissiveness;

            if (score >= 0)
            {
                check.Result = BdsmTraitOperationCheckResult.InCompliance;
            }
            else
            {
                const int rollMaximum = 100;
                check.RequiredValue = (int)Math.Round(rollMaximum * Janchsinus(score));
                check.RolledValue   = ThreadSafeRandom.Next(1, rollMaximum + 1);
                check.RollMaximum   = rollMaximum;

                if (check.RolledValue >= check.RequiredValue)
                {
                    check.Result = BdsmTraitOperationCheckResult.RollSucceeded;
                }
                else
                {
                    check.Result = BdsmTraitOperationCheckResult.RollFailed;
                }
            }

            return(check);
        }