/// <summary>
        /// Updates the assignment message with any potential changes to the assignable roles.
        /// </summary>
        /// <param name="discordGuild">The guild that is being operated on</param>
        /// <returns>The assignment message</returns>
        private async Task <IMessage> UpdateAssignerMessage(SocketGuild discordGuild)
        {
            var guild           = GuildRepo.Get(discordGuild.Id);
            var assignerChannel = discordGuild.GetChannel(guild.Settings.RoleAssignment.ChannelId.Value) as SocketTextChannel;

            IUserMessage assignerMessage = assignerChannel.GetCachedMessage(guild.Settings.RoleAssignment.MessageId.Value) as SocketUserMessage;

            if (assignerMessage == null)
            {
                assignerMessage = await assignerChannel.GetMessageAsync(guild.Settings.RoleAssignment.MessageId.Value) as RestUserMessage;
            }

            // Search for any roles that may have been deleted without WhiffBot's knowledge
            // and delete those rows from the database.
            foreach (var role in guild.Settings.RoleAssignment.Roles)
            {
                if (discordGuild.GetRole(role.RoleId) == null)
                {
                    GuildRepo.RemoveAssignableRole(guild.Id, role.RoleId);
                    await assignerMessage.RemoveAllReactionsForEmoteAsync(role.Reaction.ToEmojiOrEmote());

                    guild = GuildRepo.Get(discordGuild.Id);
                }
            }

            var newContent = CreateAssignerMessage(discordGuild, guild.Settings.RoleAssignment);
            await assignerMessage.ModifyAsync(m => m.Content = newContent);

            return(assignerMessage);
        }
Exemple #2
0
        public async Task ProcessVoteCommandAsync(IUserMessage voteCommandMessage, string voteDefinitionText)
        {
            if (voteCommandMessage.Channel is not IGuildChannel guildChannel)
            {
                return;
            }

            var parse = await Parser.TryParse(new CommandContext(Client, voteCommandMessage), voteDefinitionText);

            if (!parse.Success)
            {
                await UpdateVoteReplyAsync(voteCommandMessage, parse.ProblemDescription);

                return;
            }

            var allEmotes = new HashSet <IEmote>(parse.Definition.Options.Keys);

            allEmotes.UnionWith(voteCommandMessage.Reactions.Keys);
            var failedEmotes = new List <IEmote>();
            var summary      = ComposeSummary(voteCommandMessage, parse.Definition);

            foreach (var emote in allEmotes)
            {
                var shouldBePresent = parse.Definition.Options.ContainsKey(emote);
                var isPresent       = voteCommandMessage.Reactions.TryGetValue(emote, out var reaction);

                if (!shouldBePresent && isPresent)
                {
                    await voteCommandMessage.RemoveAllReactionsForEmoteAsync(emote);
                }
                else if (shouldBePresent && !isPresent)
                {
                    try
                    {
                        await voteCommandMessage.AddReactionAsync(emote);
                    }
                    catch (HttpException)
                    {
                        failedEmotes.Add(emote);
                    }
                }
            }

            var tail = failedEmotes.Count == 0
                ? string.Empty
                : Environment.NewLine + string.Format(
                VoteTranslations.UnaccessibleEmotes,
                new FormatByValue(failedEmotes.Count),
                string.Join(", ", failedEmotes.Select(e => $"`{e}`"))
                );

            await UpdateVoteReplyAsync(voteCommandMessage, summary + tail);

            if (parse.Definition.Deadline is DateTimeOffset votingDeadline)
            {
                var scheduledTaskTag = voteCommandMessage.GetJumpUrl();

                var previouslyScheduledEndsOfVote = await ScheduledTasksService.LookupAsync(EndOfVotingScheduledTask.Identifier, scheduledTaskTag);

                foreach (var endOfVoteTask in previouslyScheduledEndsOfVote)
                {
                    await ScheduledTasksService.CancelAsync(endOfVoteTask.ScheduledTaskId);
                }

                await ScheduledTasksService.EnqueueAsync(new ScheduledTask
                {
                    Discriminator = EndOfVotingScheduledTask.Identifier,
                    Tag           = scheduledTaskTag,
                    When          = votingDeadline,
                    Data          = JsonConvert.SerializeObject(new EndOfVotingScheduledTask
                    {
                        GuildId   = guildChannel.GuildId,
                        ChannelId = guildChannel.Id,
                        MessageId = voteCommandMessage.Id
                    })
                });
            }
        }