示例#1
0
 public IAsyncEnumerable <IReadOnlyCollection <IUser> > GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null)
 {
     throw new NotImplementedException();
 }
示例#2
0
 /// <inheritdoc />
 public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
 => MessageHelper.AddReactionAsync(this, emote, Discord, options);
示例#3
0
 /// <inheritdoc />
 public Task RemoveAllReactionsForEmoteAsync(IEmote emote, RequestOptions options = null)
 => MessageHelper.RemoveAllReactionsForEmoteAsync(this, emote, Discord, options);
示例#4
0
        public static async Task <IReadOnlyCollection <IUser> > GetReactionUsersAsync(IMessage msg, IEmote emote,
                                                                                      Action <GetReactionUsersParams> func, BaseDiscordClient client, RequestOptions options)
        {
            var args = new GetReactionUsersParams();

            func(args);
            string emoji = (emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name);

            return((await client.ApiClient.GetReactionUsersAsync(msg.Channel.Id, msg.Id, emoji, args, options).ConfigureAwait(false)).Select(u => RestUser.Create(client, u)).ToImmutableArray());
        }
示例#5
0
        public async static Task RPSProcessor(Cacheable <IUserMessage, ulong> cachedEntity, ISocketMessageChannel channel, SocketReaction reaction)
        {
            var message      = (SocketUserMessage)cachedEntity.Value;
            var reactingUser = (SocketUser)reaction.User;

            if (reactingUser.IsBot || message == null)
            {
                return;
            }

            if (message.Content.StartsWith("Game over: "))
            {
                if (message.Reactions.ContainsKey(new Emoji("❗")))
                {
                    await message.ModifyAsync(x => x.Content = "Choose Rock, Paper, or Scissors!");

                    await message.RemoveAllReactionsAsync();

                    IEmote[] rpsReactions = new IEmote[]
                    {
                        new Emoji("🪨"),
                        new Emoji("🧻"),
                        new Emoji("✂️"),
                        new Emoji("❗"),
                    };

                    await message.AddReactionsAsync(rpsReactions);
                }
            }

            if (message.Content == "Choose Rock, Paper, or Scissors!")
            {
                var    reactions     = message.Reactions;
                IEmote usersReaction = null;

                foreach (var r in reactions)
                {
                    if (r.Value.ReactionCount > 1)
                    {
                        usersReaction = r.Key;
                    }
                }

                ThrowResult playerThrow = (ThrowResult)(-1);
                if (usersReaction.Name == "🪨")
                {
                    playerThrow = ThrowResult.Rock;
                }
                else if (usersReaction.Name == "🧻")
                {
                    playerThrow = ThrowResult.Paper;
                }
                else if (usersReaction.Name == "✂️")
                {
                    playerThrow = ThrowResult.Scissors;
                }
                else
                {
                    return;
                }

                ThrowResult computerThrow = EnumHelper.RandomEnumValue <ThrowResult>();
                var         winner        = DetermineWinner(computerThrow, playerThrow);

                string outputMessage = "Game over: ";
                if (winner == Winner.Bot)
                {
                    outputMessage += $"{ message.Author.Mention } *won* by throwing { GetEmoji(computerThrow) } against { usersReaction.Name}!";
                }
                else if (winner == Winner.Player)
                {
                    outputMessage += $"{ reactingUser.Mention } *won* by throwing { usersReaction.Name} against { GetEmoji(computerThrow) }!";
                }
                else
                {
                    outputMessage += $"It's a tie! { GetEmoji(computerThrow)} vs { GetEmoji(playerThrow) }!";
                }

                await message.ModifyAsync(msg => msg.Content = outputMessage);
            }
        }
 public bool TryGetValue(IEmote key, out ulong roleId) => TryGetValue(key.ToString(), out roleId);
示例#7
0
 public Reaction(string text, IEmote emote)
 {
     this.text   = text;
     this.emotes = new IEmote[] { emote };
 }
示例#8
0
 public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
 {
     throw new NotImplementedException();
 }
示例#9
0
 public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
 {
     throw new NotImplementedException();
 }
示例#10
0
 /// <inheritdoc />
 public IAsyncEnumerable <IReadOnlyCollection <IUser> > GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null)
 => RestUserMessage.GetReactionUsersAsync(emoji, limit, options)
 .Select(x => x
         .Select(UserAbstractionExtensions.Abstract)
         .ToArray());
示例#11
0
 /// <inheritdoc />
 public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
 => RestUserMessage.RemoveReactionAsync(emote, user, options);
示例#12
0
 /// <inheritdoc />
 public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
 => RestUserMessage.AddReactionAsync(emote, options);
示例#13
0
 internal SocketReaction(ISocketMessageChannel channel, ulong messageId, Optional <SocketUserMessage> message, ulong userId, Optional <IUser> user, IEmote emoji)
 {
     Channel   = channel;
     MessageId = messageId;
     Message   = message;
     UserId    = userId;
     User      = user;
     Emote     = emoji;
 }
示例#14
0
 public Task <IReadOnlyCollection <IUser> > GetReactionUsersAsync(IEmote emoji, int limit = 100, ulong?afterUserId = null, RequestOptions options = null)
 {
     throw new NotImplementedException();
 }
 internal void RemoveReactionsForEmote(IEmote emote)
 {
     _reactions.RemoveAll(x => x.Emote.Equals(emote));
 }
        public async Task <bool> IsSaveReaction(ulong guildId, IEmote emote)
        {
            var settings = await GetGuildSettings(guildId);

            return(settings.SaveReaction == emote.ToString());
        }
示例#17
0
 public ulong this[IEmote key]
 {
     get => this[key.ToString()];
     set => this[key.ToString()] = value;
示例#18
0
        public async Task <SocketReaction> WaitForReactionAsync(SocketCommandContext context, IMessage message, IEmote expectedEmote)
        {
            var token   = new CancellationToken();
            var timeout = TimeSpan.FromSeconds(120);

            var eventTrigger  = new TaskCompletionSource <SocketReaction>();
            var cancelTrigger = new TaskCompletionSource <bool>();

            token.Register(() => cancelTrigger.SetResult(true));

            var sourceContext = context;

            AddReactionCallback(message, new AsyncReactionCallback(sourceContext, reaction =>
            {
                if (reaction.Emote.Name.Equals(expectedEmote.Name, StringComparison.Ordinal))
                {
                    eventTrigger.SetResult(reaction);
                    return(Task.FromResult(true));
                }

                return(Task.FromResult(false));
            }));

            try
            {
                var trigger = eventTrigger.Task;
                var cancel  = cancelTrigger.Task;
                var delay   = Task.Delay(timeout);
                var task    = await Task.WhenAny(trigger, delay, cancel).ConfigureAwait(false);

                if (task == trigger)
                {
                    return(await trigger.ConfigureAwait(false));
                }
                else
                {
                    return(null);
                }
            }
            catch
            {
                return(null);
            }
            finally
            {
                RemoveReactionCallback(message);
            }
        }
示例#19
0
 public bool Remove(IEmote key) => Remove(key.ToString());
示例#20
0
 public Task <IReadOnlyCollection <IUser> > GetReactionUsersAsync(IEmote emote, int limit = 100, ulong?afterUserId = null, RequestOptions options = null)
 => MessageHelper.GetReactionUsersAsync(this, emote, x => { x.Limit = limit; x.AfterUserId = afterUserId ?? Optional.Create <ulong>(); }, Discord, options);
示例#21
0
 public static async Task RemoveReactionAsync(IMessage msg, IUser user, IEmote emote, BaseDiscordClient client, RequestOptions options)
 {
     await client.ApiClient.RemoveReactionAsync(msg.Channel.Id, msg.Id, user.Id, emote is Emote e?$"{e.Name}:{e.Id}" : emote.Name, options).ConfigureAwait(false);
 }
示例#22
0
        public IEmoteButton Create(IEmote emote, ulong messageId, ButtonTrigger trigger)
        {
            var emoteButton = new EmoteButton(_client, emote, messageId, trigger);

            return(emoteButton);
        }
示例#23
0
        public async Task Poll(string title, string prompt, params string[] options)
        {
            string[] configEmotes = Nitori.Config.pollEmotes;
            if (options.Length > configEmotes.Length)
            {
                await ReplyAsync(string.Format(ResponseManager.GetLine("PollTooManyArgs"), options.Length, configEmotes.Length));

                return;
            }

            //await Context.Message.DeleteAsync();
            SocketUser pollOwner = Context.User;
            SocketUser bot       = Context.Client.CurrentUser;

            IEmote[] emotes = new IEmote[options.Length];

            EmbedBuilder embed = new EmbedBuilder()
                                 .WithTitle("📊 " + title)
                                 .WithDescription(prompt)
                                 .WithAuthor(author => author.WithName($"{pollOwner.Username} started a poll:").WithIconUrl(pollOwner.GetAvatarUrl()))
                                 .WithColor(6798951)
                                 .WithCurrentTimestamp()
                                 .WithFooter(footer => footer.WithText("A bot tailored for /r/weather").WithIconUrl(bot.GetAvatarUrl()));


            int count = 0;  // Too lazy to make an actual for loop lmao

            foreach (string option in options)
            {
                string emoteString = configEmotes[count];
                IEmote emote;
                if (Emote.TryParse(emoteString, out Emote e))
                {
                    emote = e;
                }
                else
                {
                    emote = new Emoji(emoteString);
                }

                embed.AddField($"{emote.Name} " + option, $"Emote below to pick '**{option}**'.");

                emotes[count] = emote;
                count++;
            }
            IUserMessage message = await ReplyAsync(embed : embed.Build());

            await message.AddReactionsAsync(emotes);

            await Task.Delay(20 * 1000);


            message = await Context.Channel.GetMessageAsync(message.Id) as IUserMessage;    // Download message again to get the updated reacts

            int[] score       = new int[options.Length];
            int   winningVote = 0;

            count = 0;
            foreach (IEmote emote in emotes)
            {
                int votes = message.Reactions[emote].ReactionCount - 1; // -1 because of the bot also counting itself.
                score[count] = votes;
                count++;
            }

            winningVote = score.Max();

            EmbedBuilder resultEmbed = new EmbedBuilder()
                                       .WithTitle($"📊 Results for {title}")
                                       .WithAuthor(author => author.WithName($"{pollOwner.Username}'s poll:").WithIconUrl(pollOwner.GetAvatarUrl()))
                                       .WithCurrentTimestamp()
                                       .WithFooter(footer => footer.WithText("A bot tailored for /r/weather").WithIconUrl(bot.GetAvatarUrl()));

            if (score.All(x => x == 0))
            {
                resultEmbed.WithColor(13576232)
                .WithDescription(ResponseManager.GetLine("PollResultNoVotes"));
            }
            else if (score.Count(x => x == winningVote) > 1)
            {
                for (int i = 0; i < options.Length; i++)
                {
                    if (score[i] == winningVote)
                    {
                        IEmote emote = emotes[i];
                        resultEmbed.AddField($"{emote.Name} - {options[i]}",
                                             $"{winningVote} votes.",
                                             true);
                    }
                }

                resultEmbed.WithColor(13576232)
                .WithDescription(ResponseManager.GetLine("PollResultTie"));
            }
            else
            {
                int    index = Array.IndexOf(score, winningVote);
                IEmote emote = emotes[index];
                resultEmbed.WithColor(6798951)
                .WithDescription(ResponseManager.GetLine("PollResultSuccess"))
                .AddField($"{emote.Name} - {options[index]}", $"{winningVote} votes.");
            }

            // Failed attempt to make a unique vote guard below

            /*
             * Dictionary<IEmote, List<IUser>> userList = new Dictionary<IEmote, List<IUser>>();
             *
             * foreach (IEmote emote in emotes)
             * {
             *  userList.Add(emote, new List<IUser>(await message.GetReactionUsersAsync(emote, count + 1).FlattenAsync()));
             *  userList[emote].Remove(Context.Client.CurrentUser);
             * }
             *
             * List<IUser> duplicateUsers = userList.Values.Cast<IEnumerable<IUser>>() // List of users that voted more than once
             *  .Aggregate((accumulator, list) => accumulator.Concat(list)) // Concatenates every list into one
             *  .GroupBy(x => Context.Guild.GetUser(x.Id) as IUser)         // Groups elements based on if they're the same element
             *  .Where(g => g.Count() > 1)  // Filters groups that only appear once (distinct elements)
             *  .Select(g => g.Key)         // ??? what the f**k is this
             *  .ToList();                  // Converts to list
             *
             * List<int> scores = new List<int>();
             * int winner = 0;
             * foreach (List<IUser> users in userList.Values)
             * {
             *  foreach (IUser loser in duplicateUsers)
             *  {
             *      users.Remove(loser);
             *  }
             *  scores.Add(users.Count);
             * }
             * scores.ForEach(x => winner = Math.Max(winner, x));
             *
             * foreach (IUser loser in duplicateUsers) {
             *  foreach (List<IUser> users in userList.Values)
             *  {
             *      users.Remove(loser);
             *  }
             * }
             */
            await ReplyAsync(embed : resultEmbed.Build());

            //await message.Reac
        }
示例#24
0
 public Task AddReactionAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null)
 => MessageHelper.AddReactionAsync(channelId, messageId, emote, this, options);
示例#25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ReactionCondition"/> class.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="emote">The required reaction.</param>
 public ReactionCondition(IMessage message, IEmote emote)
     : this((long)message.Channel.Id, (long)message.Id, emote.Name)
 {
 }
示例#26
0
 public Task RemoveAllReactionsForEmoteAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null)
 => MessageHelper.RemoveAllReactionsForEmoteAsync(channelId, messageId, emote, this, options);
示例#27
0
 /// <inheritdoc />
 public Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions options = null)
 => MessageHelper.RemoveReactionAsync(this, userId, emote, Discord, options);
示例#28
0
        public async Task RRaddCommand(params string[] args)
        {
            switch (args.Length)
            {
            case 0 or 1 or 2:
                await ReplyAsync("", false, new EmbedBuilder
                {
                    Title       = "Insufficient Parameters",
                    Description =
                        $"The way to use the command is `{await SqliteClass.PrefixGetter(Context.Guild.Id)}readd <link-to-message> <emoji> <role>`",
                    Color = Color.Red
                }.WithCurrentTimestamp());

                return;
            }

            var reg = new Regex(@"^https:\/\/discord.com\/channels\/[0-9]{17,18}\/[0-9]{17,18}\/[0-9]{17,18}$");

            if (!reg.IsMatch(args[0]))
            {
                await ReplyAsync("", false, new EmbedBuilder
                {
                    Title       = "Which message?",
                    Description = $"Couldn't parse `{args[0]}` as a Discord Message link",
                    Color       = Color.Red
                }.WithCurrentTimestamp());

                return;
            }

            var dry     = args[0].Replace(@"https://discord.com/channels/", "").Split('/');
            var chnlid  = ulong.Parse(dry[1]);
            var msgid   = ulong.Parse(dry[2]);
            var channel = Context.Guild.GetTextChannel(chnlid);

            if (channel == null)
            {
                await ReplyAsync("", false, new EmbedBuilder
                {
                    Title       = "Which message?",
                    Description =
                        $"Couldn't parse `{args[0]}` as a Discord Message link\nHint: We cannot find the channel. This might be due to Permissions, or that Channel (and Message) is from another server.",
                    Color = Color.Red
                }.WithCurrentTimestamp());

                return;
            }

            var message = await channel.GetMessageAsync(msgid);

            if (message == null)
            {
                await ReplyAsync("", false, new EmbedBuilder
                {
                    Title       = "Which message?",
                    Description =
                        $"Couldn't parse `{args[0]}` as a Discord Message link\nHint: We cannot find the message. This might be due to deletion or permissions.",
                    Color = Color.Red
                }.WithCurrentTimestamp());

                return;
            }

            var    isEmote = Emote.TryParse(args[1], out var emz);
            IEmote em      = emz;

            if (isEmote == false)
            {
                var el = new Emoji(args[1]);
                if (el == null)
                {
                    await ReplyAsync("", false, new EmbedBuilder
                    {
                        Title       = "Which emote?",
                        Description = $"Couldn't parse `{args[1]}` as an emote :(",
                        Color       = Color.Red
                    }.WithCurrentTimestamp());

                    return;
                }

                em = el;
            }

            var role = GetRole(args[2]);

            if (role == null)
            {
                await ReplyAsync("", false, new EmbedBuilder
                {
                    Title       = "Which role?",
                    Description = $"Couldn't parse `{args[2]}` as a role :(",
                    Color       = Color.Red
                }.WithCurrentTimestamp());

                return;
            }

            var reros = await SqliteClass.GetReactRoleAsync(
                $"SELECT * FROM reactroles WHERE ChannelID = {chnlid} AND MessageID = {msgid}");

            SqliteClass.ReactRole rero;
            if (reros.Count == 0)
            {
                rero = new SqliteClass.ReactRole
                {
                    ChannelId = chnlid,
                    MessageId = msgid,
                    GuildId   = Context.Guild.Id,
                    Emojis    = new List <string> {
                        em.ToString()
                    },
                    Roles = new List <ulong> {
                        role.Id
                    },
                    BlackListedRoles = new ulong[] { },
                    WhiteListedRoles = new ulong[] { },
                    Unique           = false,
                    SelfDestructTime = DateTime.MinValue
                };
            }
            else
            {
                rero = reros[0];
                rero.Roles.Add(role.Id);
                rero.Emojis.Add(em.ToString());
            }

            await SqliteClass.AddOrUpdateReactRole(rero);

            await message.AddReactionAsync(em);

            await ReplyAsync("", false, new EmbedBuilder
            {
                Title       = "Reaction Role added successfully!",
                Description = $"[Jump]({args[0]})",
                Color       = Blurple
            }.WithCurrentTimestamp());
        }
示例#29
0
 /// <inheritdoc />
 public IAsyncEnumerable <IReadOnlyCollection <IUser> > GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
 => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
        public async Task <bool> HandleReactionAddedAsync(IUserMessage message, IEmote reaction, IUser user)
        {
            var embed = message.Embeds.FirstOrDefault();

            if (embed == null || embed.Author == null || embed.Footer == null)
            {
                return(false); // Embed checks
            }
            if (!ReactionSettings.PaginationReactions.Any(emote => emote.IsEqual(reaction)))
            {
                return(false); // Reaction check.
            }
            if (message.ReferencedMessage == null)
            {
                return(false);
            }

            if (!embed.TryParseMetadata <HelpPageEmbedMetadata>(out var metadata))
            {
                return(false); // Not a help embed.
            }
            var context          = new CommandContext(Client, message.ReferencedMessage);
            var availableModules = await CommandService.Modules
                                   .FindAllAsync(async mod => (await mod.GetExecutableCommandsAsync(context, Provider)).Count > 0);

            int maxPages = Math.Min(metadata.PageCount, availableModules.Count); // Maximal count of available pages.
            int newPage  = metadata.PageNumber;

            if (reaction.IsEqual(ReactionSettings.MoveToFirst))
            {
                newPage = 1;
            }
            else if (reaction.IsEqual(ReactionSettings.MoveToLast))
            {
                newPage = maxPages;
            }
            else if (reaction.IsEqual(ReactionSettings.MoveToNext) && newPage < maxPages)
            {
                newPage++;
            }
            else if (reaction.IsEqual(ReactionSettings.MoveToPrevious) && newPage > 1)
            {
                newPage--;
            }

            if (newPage != metadata.PageNumber)
            {
                var module   = availableModules[newPage - 1];
                var newEmbed = (await new HelpPageEmbed()
                                .WithModuleAsync(module, context, Provider, maxPages, Configuration["Prefix"], newPage))
                               .Build();

                await message.ModifyAsync(msg => msg.Embed = newEmbed);
            }

            if (!context.IsPrivate) // DMs have blocked removing reactions.
            {
                await message.RemoveReactionAsync(reaction, user);
            }
            return(true);
        }