public IAsyncEnumerable <IReadOnlyCollection <IUser> > GetReactionUsersAsync(IEmote emoji, int limit, RequestOptions options = null) { throw new NotImplementedException(); }
/// <inheritdoc /> public Task AddReactionAsync(IEmote emote, RequestOptions options = null) => MessageHelper.AddReactionAsync(this, emote, Discord, options);
/// <inheritdoc /> public Task RemoveAllReactionsForEmoteAsync(IEmote emote, RequestOptions options = null) => MessageHelper.RemoveAllReactionsForEmoteAsync(this, emote, Discord, options);
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()); }
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);
public Reaction(string text, IEmote emote) { this.text = text; this.emotes = new IEmote[] { emote }; }
public Task AddReactionAsync(IEmote emote, RequestOptions options = null) { throw new NotImplementedException(); }
public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null) { throw new NotImplementedException(); }
/// <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());
/// <inheritdoc /> public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null) => RestUserMessage.RemoveReactionAsync(emote, user, options);
/// <inheritdoc /> public Task AddReactionAsync(IEmote emote, RequestOptions options = null) => RestUserMessage.AddReactionAsync(emote, options);
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; }
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()); }
public ulong this[IEmote key] { get => this[key.ToString()]; set => this[key.ToString()] = value;
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); } }
public bool Remove(IEmote key) => Remove(key.ToString());
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);
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); }
public IEmoteButton Create(IEmote emote, ulong messageId, ButtonTrigger trigger) { var emoteButton = new EmoteButton(_client, emote, messageId, trigger); return(emoteButton); }
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 }
public Task AddReactionAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null) => MessageHelper.AddReactionAsync(channelId, messageId, emote, this, options);
/// <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) { }
public Task RemoveAllReactionsForEmoteAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null) => MessageHelper.RemoveAllReactionsForEmoteAsync(channelId, messageId, emote, this, options);
/// <inheritdoc /> public Task RemoveReactionAsync(IEmote emote, ulong userId, RequestOptions options = null) => MessageHelper.RemoveReactionAsync(this, userId, emote, Discord, options);
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()); }
/// <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); }