public static Task RemoveReactionAsync(this IRestClient client,
                                               Snowflake channelId, Snowflake messageId, LocalEmoji emoji, Snowflake userId,
                                               IRestRequestOptions options = null, CancellationToken cancellationToken = default)
        {
            Guard.IsNotNull(emoji);

            if (client.ApiClient.Token is BotToken botToken && botToken.Id == userId)
            {
                return(client.ApiClient.RemoveOwnReactionAsync(channelId, messageId, emoji.GetReactionFormat(), options, cancellationToken));
            }

            return(client.ApiClient.RemoveUserReactionAsync(channelId, messageId, emoji.GetReactionFormat(), userId, options, cancellationToken));
        }
        public static IPagedEnumerable <IUser> EnumerateReactions(this IRestClient client,
                                                                  Snowflake channelId, Snowflake messageId, LocalEmoji emoji, int limit, Snowflake?startFromId = null,
                                                                  IRestRequestOptions options = null)
        {
            Guard.IsNotNull(emoji);
            Guard.IsGreaterThanOrEqualTo(limit, 0);

            return(PagedEnumerable.Create((state, cancellationToken) =>
            {
                var(client, channelId, messageId, emoji, limit, startFromId, options) = state;
                return new FetchReactionsPagedEnumerator(client, channelId, messageId, emoji, limit, startFromId, options, cancellationToken);
            }, (client, channelId, messageId, emoji, limit, startFromId, options)));
        }
        public static Task ClearReactionsAsync(this IMessage message, LocalEmoji emoji = null, IRestRequestOptions options = null)
        {
            var client = message.GetRestClient();

            return(client.ClearReactionsAsync(message.ChannelId, message.Id, emoji, options));
        }
        public static Task RemoveOwnReactionAsync(this IRestClient client,
                                                  Snowflake channelId, Snowflake messageId, LocalEmoji emoji,
                                                  IRestRequestOptions options = null, CancellationToken cancellationToken = default)
        {
            Guard.IsNotNull(emoji);

            return(client.ApiClient.RemoveOwnReactionAsync(channelId, messageId, emoji.GetReactionFormat(), options, cancellationToken));
        }
        public static Task <IReadOnlyList <IUser> > FetchReactionsAsync(this IMessageChannel channel, Snowflake messageId, LocalEmoji emoji, int limit = 100, Snowflake?startFromId = null, IRestRequestOptions options = null)
        {
            var client = channel.GetRestClient();

            return(client.FetchReactionsAsync(channel.Id, messageId, emoji, limit, startFromId, options));
        }
        public static Task RemoveReactionAsync(this IRestClient client, Snowflake channelId, Snowflake messageId, LocalEmoji emoji, Snowflake userId, IRestRequestOptions options = null)
        {
            if (emoji == null)
            {
                throw new ArgumentNullException(nameof(emoji));
            }

            if (client.ApiClient.Token is BotToken botToken && botToken.Id == userId)
            {
                return(client.ApiClient.RemoveOwnReactionAsync(channelId, messageId, emoji.GetReactionFormat(), options));
            }

            return(client.ApiClient.RemoveUserReactionAsync(channelId, messageId, emoji.GetReactionFormat(), userId, options));
        }
Example #7
0
 public SelectionPage(Func <Task <Page> > pageFunc, string selectionLabel, string selectionDescription = null, LocalEmoji selectionEmoji = null)
 {
     _pageFunc            = pageFunc;
     SelectionLabel       = selectionLabel;
     SelectionDescription = selectionDescription;
     SelectionEmoji       = selectionEmoji;
 }
        public static Task ClearReactionsAsync(this IRestClient client,
                                               Snowflake channelId, Snowflake messageId, LocalEmoji emoji = null,
                                               IRestRequestOptions options = null, CancellationToken cancellationToken = default)
        {
            if (emoji == null)
            {
                return(client.ApiClient.ClearReactionsAsync(channelId, messageId, options, cancellationToken));
            }

            return(client.ApiClient.ClearEmojiReactionsAsync(channelId, messageId, emoji.GetReactionFormat(), options, cancellationToken));
        }
Example #9
0
 public static TComponent WithEmoji <TComponent>(this TComponent component, LocalEmoji emoji)
     where TComponent : LocalButtonComponentBase
 {
     component.Emoji = emoji;
     return(component);
 }
Example #10
0
 public SelectionPage(Page page, string selectionLabel, string selectionDescription = null, LocalEmoji selectionEmoji = null)
 {
     _page                = page;
     SelectionLabel       = selectionLabel;
     SelectionDescription = selectionDescription;
     SelectionEmoji       = selectionEmoji;
 }
 public DiscordReactionCommandResult(DiscordCommandContext context, LocalEmoji emoji)
     : base(context)
 {
     Emoji = emoji;
 }
        public static Task <IReadOnlyList <IUser> > FetchReactionsAsync(this IRestClient client, Snowflake channelId, Snowflake messageId, LocalEmoji emoji, int limit = 100, Snowflake?startFromId = null, IRestRequestOptions options = null)
        {
            if (emoji == null)
            {
                throw new ArgumentNullException(nameof(emoji));
            }

            if (limit == 0)
            {
                return(Task.FromResult(ReadOnlyList <IUser> .Empty));
            }

            if (limit <= 100)
            {
                return(client.InternalFetchReactionsAsync(channelId, messageId, emoji, limit, startFromId, options));
            }

            var enumerable = client.EnumerateReactions(channelId, messageId, emoji, limit, startFromId, options);

            return(enumerable.FlattenAsync());
        }
        public static IPagedEnumerable <IUser> EnumerateReactions(this IRestClient client, Snowflake channelId, Snowflake messageId, LocalEmoji emoji, int limit, Snowflake?startFromId = null, IRestRequestOptions options = null)
        {
            if (emoji == null)
            {
                throw new ArgumentNullException(nameof(emoji));
            }

            return(new PagedEnumerable <IUser>(new FetchReactionsPagedEnumerator(client, channelId, messageId, emoji, limit, startFromId, options)));
        }
        public static Task <IReadOnlyList <IUser> > FetchReactionsAsync(this IRestClient client,
                                                                        Snowflake channelId, Snowflake messageId, LocalEmoji emoji, int limit = Discord.Limits.Rest.FetchReactionsPageSize, Snowflake?startFromId = null,
                                                                        IRestRequestOptions options = null, CancellationToken cancellationToken = default)
        {
            Guard.IsNotNull(emoji);

            if (limit == 0)
            {
                return(Task.FromResult(ReadOnlyList <IUser> .Empty));
            }

            if (limit <= Discord.Limits.Rest.FetchReactionsPageSize)
            {
                return(client.InternalFetchReactionsAsync(channelId, messageId, emoji, limit, startFromId, options, cancellationToken));
            }

            var enumerable = client.EnumerateReactions(channelId, messageId, emoji, limit, startFromId, options);

            return(enumerable.FlattenAsync(cancellationToken));
        }
        public static Task <IReadOnlyList <IUser> > FetchReactionsAsync(this IMessageChannel channel,
                                                                        Snowflake messageId, LocalEmoji emoji, int limit = Discord.Limits.Rest.FetchReactionsPageSize, Snowflake?startFromId = null,
                                                                        IRestRequestOptions options = null, CancellationToken cancellationToken = default)
        {
            var client = channel.GetRestClient();

            return(client.FetchReactionsAsync(channel.Id, messageId, emoji, limit, startFromId, options, cancellationToken));
        }
        internal static async Task <IReadOnlyList <IUser> > InternalFetchReactionsAsync(this IRestClient client,
                                                                                        Snowflake channelId, Snowflake messageId, LocalEmoji emoji, int limit, Snowflake?startFromId,
                                                                                        IRestRequestOptions options, CancellationToken cancellationToken)
        {
            var models = await client.ApiClient.FetchReactionsAsync(channelId, messageId, emoji.GetReactionFormat(), limit, startFromId, options, cancellationToken).ConfigureAwait(false);

            return(models.ToReadOnlyList(client, (x, client) => new TransientUser(client, x)));
        }
Example #17
0
#pragma warning disable 1998
        async Task HandleMessageReceived(MessageReceivedEventArgs e)
#pragma warning restore 1998
        {
            // purge old pending claims (avoids memory leak)
            foreach (var id in _pendingClaims.Keys)
            {
                if (_pendingClaims.TryGetValue(id, out var claim) && claim.CreatedTime.AddMinutes(1) < DateTime.Now)
                {
                    _pendingClaims.TryRemove(id, out _);
                }
            }

            foreach (var id in _pendingKakeraClaims.Keys)
            {
                if (_pendingKakeraClaims.TryGetValue(id, out var claim) && claim.CreatedTime.AddMinutes(1) < DateTime.Now)
                {
                    _pendingKakeraClaims.TryRemove(id, out _);
                }
            }

            var options = _options.CurrentValue;

            // enabled, message author is mudae, channel is configured, embed exists
            if (!options.Enabled || !(e.Message is IUserMessage message && _userFilter.IsMudae(message.Author)) || _channelList.CurrentValue.Items.All(x => x.Id != message.ChannelId) || message.Embeds.Count == 0)
            {
                return;
            }

            var stopwatch = Stopwatch.StartNew();

            var channel = (IMessageChannel)e.Client.GetChannel(message.ChannelId);
            var guild   = channel is IGuildChannel gc?e.Client.GetGuild(gc.GuildId) : null;

            var logPlace = $"channel '{channel.Name}' ({channel.Id}, server '{guild?.Name}')";

            var embed       = message.Embeds[0];
            var description = embed.Description.Split('\n', StringSplitOptions.RemoveEmptyEntries);
            var character   = new CharacterInfo(embed.Author.Name, description[0]);

            // ignore $im messages
            if (!options.BypassImCheck && description.Any(l => l.StartsWith("claim rank:", StringComparison.OrdinalIgnoreCase) || l.StartsWith("like rank:", StringComparison.OrdinalIgnoreCase)))
            {
                return;
            }

            _logger.LogDebug($"Detected character '{character}' in {logPlace}.");

            _pendingKakeraClaims[message.Id] = new PendingClaim(logPlace, channel, message, character, stopwatch);

            // ignore already claimed
            if (embed.Footer?.Text.StartsWith("belongs", StringComparison.OrdinalIgnoreCase) == true)
            {
                return;
            }

            var wishedBy = message.Content.StartsWith("wished by", StringComparison.OrdinalIgnoreCase) ? message.GetUserIds().ToArray() : null;

            // must be wished or included in a user wishlist
            if (!_characterFilter.IsWished(character, wishedBy))
            {
                _logger.LogInformation($"Ignoring character '{character}' in {logPlace} because they are not wished.");
                return;
            }

            // check cooldown
            var state = _states.GetOrAdd(channel.Id, new ClaimState());
            var now   = DateTime.Now;

            if (!options.IgnoreCooldown && now < state.CooldownResetTime)
            {
                _logger.LogWarning($"Ignoring character '{character}' in {logPlace} because of cooldown. Cooldown finishes in {state.CooldownResetTime - now}.");
                return;
            }

            _logger.LogWarning($"Attempting to claim character '{character}' in {logPlace}...");

            _pendingClaims[message.Id] = new PendingClaim(logPlace, channel, message, character, stopwatch);

            /* Claim from message event instead of reaction event */

            if (_pendingClaims.TryRemove(e.Message.Id, out var claim1))
            {
                var(logPlace1, channel1, message1, character1, stopwatch1) = claim1;

                await Task.Delay(TimeSpan.FromSeconds(options.DelaySeconds));

                var replySubs = new
                {
                    character      = character1.DisplayName.Split(' ', 2)[0].ToLowerInvariant(),
                    character_full = character1.DisplayName.ToLowerInvariant(),
                    Character      = character1.DisplayName.Split(' ', 2)[0],
                    Character_full = character1.DisplayName,

                    anime = character1.DisplayAnime.ToLowerInvariant(),
                    Anime = character1.DisplayAnime
                };

                await _replySender.SendAsync(channel1, ReplyEvent.BeforeClaim, replySubs);

                IUserMessage response;

                try
                {
                    IEmoji emoji = new LocalEmoji("\uD83D\uDC96");

                    response = await _commandHandler.ReactAsync(message1, emoji);
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"Could not claim character '{character1}' in {logPlace1}.");
                    return;
                }

                bool tryParseClaim = _outputParser.TryParseClaimSucceeded(response.Content, out var claimer, out _);
                _logger.LogDebug(response.Content);
                bool claimerEquals = claimer.Equals(e.Client.CurrentUser.Name, StringComparison.OrdinalIgnoreCase);

                _logger.LogDebug($"TryParseClaim: '{tryParseClaim}'. ClaimerEquals: '{claimerEquals}', claimer:{claimer} and user {e.Client.CurrentUser.Name}");

                if (tryParseClaim && claimerEquals)
                {
                    _logger.LogWarning($"Claimed character '{character1}' in {logPlace1} in {stopwatch1.Elapsed.TotalMilliseconds}ms.");

                    if (options.NotifyOnCharacter)
                    {
                        _notification.SendToast($"Claimed character '{character1}' in {logPlace1}.");
                    }

                    await _replySender.SendAsync(channel1, ReplyEvent.ClaimSucceeded, replySubs);

                    return;
                }

                if (_outputParser.TryParseClaimFailed(response.Content, out var resetTime))
                {
                    _states.GetOrAdd(message1.ChannelId, new ClaimState()).CooldownResetTime = DateTime.Now + resetTime;

                    _logger.LogWarning($"Could not claim character '{character1}' in {logPlace1} due to cooldown. Cooldown finishes in {resetTime}.");

                    await _replySender.SendAsync(channel1, ReplyEvent.ClaimFailed, replySubs);

                    return;
                }

                _logger.LogWarning($"Probably claimed character '{character1}' in {logPlace1}, but result could not be determined. Channel is probably busy.");

                if (options.NotifyOnCharacter)
                {
                    _notification.SendToast($"Probably claimed character '{character1}' in {logPlace1}, but result could not be determined.");
                }
            }
        }
        public static IPagedEnumerable <IUser> EnumerateReactions(this IMessageChannel channel, Snowflake messageId, LocalEmoji emoji, int limit, Snowflake?startFromId = null, IRestRequestOptions options = null)
        {
            var client = channel.GetRestClient();

            return(client.EnumerateReactions(channel.Id, messageId, emoji, limit, startFromId, options));
        }
        public static Task RemoveReactionAsync(this IMessage message, LocalEmoji emoji, Snowflake userId, IRestRequestOptions options = null)
        {
            var client = message.GetRestClient();

            return(client.RemoveReactionAsync(message.ChannelId, message.Id, emoji, userId, options));
        }
        public static Task RemoveOwnReactionAsync(this IMessageChannel channel, Snowflake messageId, LocalEmoji emoji, IRestRequestOptions options = null)
        {
            var client = channel.GetRestClient();

            return(client.RemoveOwnReactionAsync(channel.Id, messageId, emoji, options));
        }
        public static Task RemoveOwnReactionAsync(this IRestClient client, Snowflake channelId, Snowflake messageId, LocalEmoji emoji, IRestRequestOptions options = null)
        {
            if (emoji == null)
            {
                throw new ArgumentNullException(nameof(emoji));
            }

            return(client.ApiClient.RemoveOwnReactionAsync(channelId, messageId, emoji.GetReactionFormat(), options));
        }