public bool TryGetLastOperationCheck(IUser user, out BdsmTraitOperationCheck lastCheck) => Cache.TryGetValue(ToLastOperationCheckKey(user), out lastCheck);
private void SetLastOperationCheck(IUser user, BdsmTraitOperationCheck lastCheck) => Cache.Set(ToLastOperationCheckKey(user), lastCheck);
/// <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); }