private async Task AddPointsToUserAsync(IUser user, int pointsToAdd) { // Add points to current scores and global scores AddPointsCurrent(user, userScoresCurrent, pointsToAdd); var currentScore = await dbContext.TriviaScores.FirstOrDefaultAsync(s => s.GuildID == guildID && s.UserID == user.Id).ConfigureAwait(false); //pointsToAdd can be negative -> prevent less than zero points if (currentScore == null && pointsToAdd < 0) { pointsToAdd = 0; } else if (currentScore != null && currentScore.Score + pointsToAdd < 0) { pointsToAdd = -1 * currentScore.Score; } if (currentScore == null) { await dbContext.AddAsync(new TriviaScore { GuildID = guildID, UserID = user.Id, Score = pointsToAdd }).ConfigureAwait(false); } else { currentScore.Score += pointsToAdd; dbContext.Update(currentScore); } await dbContext.SaveChangesAsync().ConfigureAwait(false); }
private async Task StartPollAsync(Poll poll) { DiscordGuild guild = await _discordClient.GetGuildAsync(poll.GuildId); DiscordChannel channel = guild?.GetChannel(poll.ChannelId); DiscordMember pollCreator = await guild.GetMemberAsync(poll.CreatorId); DiscordMessage pollMessage = await channel.GetMessageAsync(poll.MessageId); pollMessage = await pollMessage.ModifyAsync(x => x.AddComponents(PollMessageUpdater.BuildAnswerButtons(poll.PossibleAnswers))); var pollMessageUpdater = PollMessageUpdater.Create(pollMessage); TimeSpan pollDuration = poll.EndTimeUTC - DateTime.UtcNow; var cancelTokenSource = new CancellationTokenSource(); cancelTokenSource.CancelAfter(pollDuration); while (!cancelTokenSource.IsCancellationRequested) { var btnClick = await pollMessage.WaitForButtonAsync(cancelTokenSource.Token); if (!btnClick.TimedOut) { var user = btnClick.Result.User; var answerId = btnClick.Result.Id; var answer = poll.PossibleAnswers.First(x => x.Id == answerId); answer.UpdateCount(user.Id); _dbContext.Update(poll); await _dbContext.SaveChangesAsync(cancelTokenSource.Token); await btnClick.Result.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage); await pollMessageUpdater.UpdateAnswers(poll.PossibleAnswers); } } var pollResult = poll.PossibleAnswers .Select(r => (Emoji: r.Emoji, Count: r.Count)) .ToList(); await pollMessageUpdater.SetAsEnded(poll.EndTimeUTC); await pollMessage.UnpinAsync(); if (!pollResult.Any(r => r.Count > 0)) { await channel.SendMessageAsync($"No one participated in the poll {poll.Question} :("); return; } Dictionary <DiscordEmoji, string> emojiMapping = GetEmojiMapping(poll.PossibleAnswers.Select(x => x.Value).ToList()); int totalVotes = pollResult.Sum(r => r.Count); var pollResultEmbed = new DiscordEmbedBuilder() .WithTitle($"Poll results: {poll.Question}") .WithColor(DiscordColor.Azure) .WithDescription( $"**{pollCreator.Mention}{(pollCreator.DisplayName.EndsWith('s') ? "'" : "'s")} poll ended. Here are the results:**\n\n" + string.Join("\n", emojiMapping .Select(ans => new { Answer = ans.Value, Votes = pollResult.Single(r => r.Emoji == ans.Key).Count }) .Select(ans => $"**{ans.Answer}**: {"vote".ToQuantity(ans.Votes)} ({100.0 * ans.Votes / totalVotes:F1} %)")) ); await channel.SendMessageAsync(embed : pollResultEmbed.Build()); _dbContext.Polls.Remove(poll); await _dbContext.SaveChangesAsync(); }