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);
        }
Beispiel #2
0
        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();
        }