Esempio n. 1
0
        private async void OnReactAdded(object sender, ReactionAddedEventArgs e)
        {
            if (!IsValidReactee(e.React))
            {
                return;
            }

            if (!IsDailyBotMessage(e.Channel, await e.Message.GetOrDownloadAsync()))
            {
                return;
            }

            if (!(e.React.Emote is Emote emote))
            {
                return;
            }

            if (!_trackedReacts.Contains(EmoteToStringCode(emote)))
            {
                return;
            }

            var message = await e.Message.GetOrDownloadAsync();

            var react = new RingFitReact
            {
                EmoteId     = EmoteToStringCode(emote),
                MessageId   = message.Id,
                UserId      = e.React.UserId,
                MessageTime = message.CreatedAt.LocalDateTime
            };

            await _dbService.InsertRingFitReact(react);
        }
Esempio n. 2
0
        private ReactionAddedEventArgs GetReactionAddedEventArgs(dynamic data)
        {
            var type = data.Value <string>("type");
            var item = data.item;
            ReactionAddedEventArgs args;
            var reaction = data["reaction"]?.ToString() ?? type;

            switch (item.Value <string>("type"))
            {
            case "file":
                args = new ReactionAddedEventArgs(reaction,
                                                  Team.Users.FirstOrDefault(x => x.Id == data.Value <string>("user")),
                                                  new SlackFile(api, data.item.Value <string>("file"),
                                                                Team.Users.FirstOrDefault(x => x.Id == data.Value <string>("item_user"))));
                break;

            case "file_comment":
                args = new ReactionAddedEventArgs(reaction,
                                                  Team.Users.FirstOrDefault(x => x.Id == data.Value <string>("user")),
                                                  new SlackFileComment(api, data.item.Value <string>("file_comment")));
                break;

            default:
                args = new ReactionAddedEventArgs(reaction,
                                                  Team.Users.FirstOrDefault(x => x.Id == data.Value <string>("user")),
                                                  MakeMessageFromData(data.item, data.Value <string>("item_user")));
                break;
            }
            return(args);
        }
Esempio n. 3
0
 public async ValueTask HandleReactionAdded(object sender, ReactionAddedEventArgs e)
 {
     foreach (var service in ReactionAddedServices)
     {
         await ExecuteAsync((service, e) => service.OnReactionAdded(e), service, e).ConfigureAwait(false);
     }
 }
Esempio n. 4
0
        private async Task HandleRaidSignupAsync(ReactionAddedEventArgs e)
        {
            if (!GetClassNames().Contains(e.Emoji.Name))
            {
                return;
            }
            if (e.User.Id == 668648526431125505 || e.User.Id == CurrentUser.Id)
            {
                return;
            }
#if DEBUG
            if (e.User.Id != 89613772372574208)
            {
                return;
            }
#else
            if (e.Channel.Id == 793661221861064715)
            {
                return;
            }
#endif
            var dbContext = this.GetRequiredService <AbfDbContext>();

            var msg = await e.Message.FetchAsync() as RestUserMessage;

            await using (dbContext)
            {
                var(check, raid, user, character) = await CheckForRaidAsync(e.Message.Id.RawValue, e.User.Id.RawValue, e.Emoji.Name, dbContext);

                if (!check)
                {
                    if (character is null)
                    {
                        var reactionUser = await e.User.FetchAsync();

                        await e.Channel.SendMessageAsync($"{reactionUser.Mention}, I didn't find a {e.Emoji.Name} character for you. Please add a character with the `!character add` command. Example: `!character add Gnomeorpuns Mage Ranged`. Do `!help character add` for full command information.");
                    }
                    await msg.RemoveMemberReactionAsync(e.User.Id, e.Emoji);

                    return;
                }

                if (raid.Participants.Any(p => p.CharacterId == character.Id))
                {
                    return;
                }

                var participant = new RaidParticipant {
                    Character = character, Raid = raid, SignedUpAt = DateTimeOffset.UtcNow
                };

                raid.Participants.Add(participant);
                dbContext.Update(raid);

                await dbContext.SaveChangesAsync();

                await WowRaidModule.CreateRaidEmbedAsync(msg, raid);
            }
        }
Esempio n. 5
0
 internal ButtonEventArgs(ReactionAddedEventArgs e) : base(e.Client)
 {
     Message  = e.Message;
     User     = e.User;
     Reaction = e.Reaction;
     Emoji    = e.Emoji;
     WasAdded = true;
 }
Esempio n. 6
0
 internal ButtonEventArgs(ReactionAddedEventArgs e)
 {
     UserId   = e.UserId;
     Message  = e.Message;
     GuildId  = e.GuildId;
     Member   = e.Member;
     Emoji    = e.Emoji;
     WasAdded = true;
 }
Esempio n. 7
0
        private async Task Bot_ReactionAdded(ReactionAddedEventArgs e)
        {
            if (e.User.HasValue && e.User.Value.IsBot)
            {
                return;
            }

            await HandleReactionAsync(e.User.Id, e.Message.Id, e.Channel.Id, e.Emoji, true);
        }
Esempio n. 8
0
        private async Task ReactionAdded(ReactionAddedEventArgs e)
        {
            if (_stopped)
            {
                return;
            }

            if (e.User.Id != User.Id || (Message != null && e.Message.Id != Message.Id))
            {
                return;
            }

            if (_hasPermission)
            {
                var msg = e.Message.Value ?? await e.Message.FetchAsync();

                await msg.RemoveMemberReactionAsync(e.User.Id, e.Emoji);
            }

            switch (e.Emoji.Name)
            {
            case "⏪":
                await PreviousPageAsync();

                break;

            case "⏩":
                await NextPageAsync();

                break;

            case "⏹":
                await StopAsync();

                break;

            case "⏮":
                await SetPageAsync(0);

                break;

            case "⏭":
                await SetPageAsync(Pages.Length - 1);

                break;

            case "🔠" when _extraEmojis:
                _ = HandleIdentifierAsync();
                break;

            case "🔢" when _extraEmojis:
                _ = HandlePageAsync();
                break;
            }
        }
        public static async Task HandleReactAddedAsync(VerificationBot bot, ReactionAddedEventArgs e)
        {
            // Guild id is null if the bot has no channel access (why does the api even send that?)
            if (e.GuildId == null || e.Member.Id == bot.CurrentUser.Id)
            {
                return;
            }

            ulong guildId = e.GuildId.Value;

            if (e.Emoji is CustomEmoji {
                Id : { RawValue : 774026811797405707 }
            })
Esempio n. 10
0
        private async void ReactionAddedAsync(object sender, ReactionAddedEventArgs e)
        {
            if (!e.React.Emote.Equals(_hamagenEmote))
            {
                return;
            }

            var reactInfo   = new ReactInfo(_config, e.Message, e.Channel, e.React);
            var warnMessage =
                $"Mayor <@{_hamagenUserId}>, one of your town villagers, <@{reactInfo.ReactAuthorId}>, requests your help!" +
                Environment.NewLine + $"Villager's letter: {reactInfo.MessageLink}";

            await _baseWarnMessageModule.WarnMessage(e.Message, e.Channel, e.React, warnMessage);
        }
Esempio n. 11
0
        private async void ReactionAddedAsync(object sender, ReactionAddedEventArgs e)
        {
            if (!e.React.Emote.Equals(_rabbit2Emoji))
            {
                return;
            }

            var reactInfo   = new ReactInfo(_config, e.Message, e.Channel, e.React);
            var warnMessage =
                $"Master <@{_jaraSoukupUserId}>, your comrade <@{reactInfo.ReactAuthorId}> has found some *steamy* discussion. You should take a look." +
                Environment.NewLine + $"Discussion reference: {reactInfo.MessageLink}";

            await _baseWarnMessageModule.WarnMessage(e.Message, e.Channel, e.React, warnMessage);
        }
Esempio n. 12
0
        private async Task HandleRaidAbsentAddedAsync(ReactionAddedEventArgs e)
        {
            if (e.Emoji.ToString() != "👋")
            {
                return;
            }
#if DEBUG
            if (e.User.Id != 89613772372574208)
            {
                return;
            }
#else
            if (e.Channel.Id == 793661221861064715)
            {
                return;
            }
#endif
            var dbContext = this.GetRequiredService <AbfDbContext>();

            await using (dbContext)
            {
                var(_, raid, user, _) = await CheckForRaidAsync(e.Message.Id.RawValue, e.User.Id.RawValue, e.Emoji.Name, dbContext);

                if (raid is null || user is null)
                {
                    return;
                }

                var userParticipants = raid.Participants.Where(rp => rp.Character.Owner.Id == e.User.Id.RawValue);

                foreach (var participant in userParticipants)
                {
                    participant.IsAbsent = true;
                    dbContext.Update(participant);
                }
                await dbContext.SaveChangesAsync();

                var msg = await e.Message.FetchAsync() as RestUserMessage;

                await WowRaidModule.CreateRaidEmbedAsync(msg, raid);
            }
        }
        private async Task HandleReactionAsync(ReactionAddedEventArgs e)
        {
            var reaction = e.Reaction;
            var message  = e.Message;

            if (e.User.Id == Discord.CurrentUser.Id)
            {
                return;
            }
            if (!(_callbacks.TryGetValue(message.Id, out var callback)))
            {
                return;
            }
            if (!await callback.Criterion.JudgeAsync(callback.Context, reaction.Value).ConfigureAwait(false))
            {
                return;
            }
            switch (callback.RunMode)
            {
            case RunMode.Parallel:
                _ = Task.Run(async() =>
                {
                    if (await callback.HandleCallbackAsync(e).ConfigureAwait(false))
                    {
                        RemoveReactionCallback(message.Id);
                    }
                });
                break;

            default:
                if (await callback.HandleCallbackAsync(e).ConfigureAwait(false))
                {
                    RemoveReactionCallback(message.Id);
                }
                break;
            }
        }
Esempio n. 14
0
        async Task HandleReactionAdded(ReactionAddedEventArgs e)
        {
            var options = _options.CurrentValue;

            if (_claimEmojiFilter.IsClaimEmoji(e.Emoji) && _pendingClaims.TryRemove(e.Message.Id, out var claim))
            {
                var(logPlace, channel, message, character, stopwatch) = claim;

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

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

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

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

                IUserMessage response;

                try
                {
                    response = await _commandHandler.ReactAsync(message, e.Emoji);
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"Could not claim character '{character}' in {logPlace}.");
                    return;
                }

                if (_outputParser.TryParseClaimSucceeded(response.Content, out var claimer, out _) && claimer.Equals(e.Client.CurrentUser.Name, StringComparison.OrdinalIgnoreCase))
                {
                    _logger.LogWarning($"Claimed character '{character}' in {logPlace} in {stopwatch.Elapsed.TotalMilliseconds}ms.");

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

                    return;
                }

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

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

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

                    return;
                }

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

            else if (_claimEmojiFilter.IsKakeraEmoji(e.Emoji, out var kakera) && _pendingKakeraClaims.TryRemove(e.Message.Id, out claim))
            {
                var(logPlace, channel, message, character, stopwatch) = claim;

                // check cooldown here (to allow skipping cooldown check for purple kakera)
                var state = _states.GetOrAdd(channel.Id, new ClaimState());
                var now   = DateTime.Now;

                if (!options.KakeraIgnoreCooldown && now < state.KakeraResetTime && kakera != KakeraType.Purple)
                {
                    return;
                }

                if (!options.KakeraTargets.Contains(kakera))
                {
                    _logger.LogInformation($"Ignoring {kakera} kakera on character '{character}' in {logPlace} because it is not targeted.");
                    return;
                }

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

                var replySubs = new
                {
                    kakera = kakera.ToString().ToLowerInvariant(),
                    Kakera = kakera.ToString()
                };

                await _replySender.SendAsync(channel, ReplyEvent.BeforeKakera, replySubs);

                IUserMessage response;

                try
                {
                    response = await _commandHandler.ReactAsync(message, e.Emoji);
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"Could not claim {kakera} kakera on character '{character}' in {logPlace}.");
                    return;
                }

                if (_outputParser.TryParseKakeraSucceeded(response.Content, out var claimer, out _) && claimer.Equals(e.Client.CurrentUser.Name, StringComparison.OrdinalIgnoreCase))
                {
                    _logger.LogWarning($"Claimed {kakera} kakera on character '{character}' in {logPlace} in {stopwatch.Elapsed.TotalMilliseconds}ms.");

                    await _replySender.SendAsync(channel, ReplyEvent.KakeraSucceeded, replySubs);

                    return;
                }

                if (_outputParser.TryParseKakeraFailed(response.Content, out var resetTime))
                {
                    state.KakeraResetTime = now + resetTime;

                    _logger.LogWarning($"Could not claim {kakera} kakera on character '{character}' in {logPlace} due to cooldown. Kakera is reset in {resetTime}.");

                    await _replySender.SendAsync(channel, ReplyEvent.KakeraFailed, replySubs);

                    return;
                }

                _logger.LogWarning($"Probably claimed {kakera} kakera on character '{character}' in {logPlace}, but result could not be determined. Channel is probably busy.");
            }
        }
Esempio n. 15
0
        private async Task ReactionAddedAsync(ReactionAddedEventArgs e)
        {
            if (!e.User.HasValue)
            {
                return;
            }
            if (e.User.Value.IsBot)
            {
                return;
            }
            if (e.Emoji == null)
            {
                return;
            }

            // Check config to see if reactions are enabled, check reaction is a translate pair for the guild
            // Respond with translated message.
            string destLang;

            if (e.Channel is IGuildChannel gChannel)
            {
                var guildId = gChannel.GuildId;
                using (var db = new DataContext())
                {
                    var guild = db.TranslateGuilds.FirstOrDefault(x => x.GuildId == guildId);
                    if (guild == null)
                    {
                        return;
                    }

                    if (guild.ReactionsEnabled == false)
                    {
                        return;
                    }

                    var reactionOverride = db.TranslatePairs.FirstOrDefault(x => x.GuildId == guildId && x.Source == e.Emoji.ReactionFormat);
                    if (reactionOverride == null)
                    {
                        // Match against default map
                        destLang = GetCode(e.Emoji.ReactionFormat)?.LanguageString;
                    }
                    else
                    {
                        destLang = reactionOverride.DestLang;
                    }

                    // TODO: Implement guild backlist/whitelist roles
                }
            }
            else
            {
                // Context should be in dm channel, bot should just respond with the translated message
                destLang = GetCode(e.Emoji.ReactionFormat)?.LanguageString;
            }

            if (destLang == null)
            {
                return;
            }
            var msg = await e.Message.FetchAsync();

            if (msg == null)
            {
                return;
            }
            if (!(msg is RestUserMessage message))
            {
                return;
            }

            if (message.Content.Length > 0)
            {
                var result = Translate(message.Content, destLang);
                if (result.ResponseResult == TranslateResponse.Result.Success)
                {
                    var embed = GetTranslationEmbed(result, message);
                    await e.Channel.SendMessageAsync("", false, embed.Build());
                }
            }

            foreach (var embed in message.Embeds)
            {
                if (embed.IsRich)
                {
                    var response = TranslateEmbed(embed, destLang, message);
                    if (response != null)
                    {
                        await e.Channel.SendMessageAsync("", false, response.Build());
                    }
                }
            }
        }
        public async Task <bool> HandleCallbackAsync(ReactionAddedEventArgs e)
        {
            var emote = e.Emoji;

            if (emote.Equals(_options.First))
            {
                page = 1;
            }
            else if (emote.Equals(_options.Next))
            {
                if (page >= pages)
                {
                    return(false);
                }
                ++page;
            }
            else if (emote.Equals(_options.Back))
            {
                if (page <= 1)
                {
                    return(false);
                }
                --page;
            }
            else if (emote.Equals(_options.Last))
            {
                page = pages;
            }
            else if (emote.Equals(_options.Stop))
            {
                await Message.DeleteAsync().ConfigureAwait(false);

                return(true);
            }
            else if (emote.Equals(_options.Jump))
            {
                _ = Task.Run(async() =>
                {
                    var criteria = new Criteria <CachedUserMessage>()
                                   .AddCriterion(new EnsureSourceChannelCriterion())
                                   .AddCriterion(new EnsureFromUserCriterion(e.User.Id))
                                   .AddCriterion(new EnsureIsIntegerCriterion());
                    var response = await Interactive.NextMessageAsync(Context, criteria, TimeSpan.FromSeconds(15));
                    var request  = int.Parse(response.Content);
                    if (request < 1 || request > pages)
                    {
                        _ = response.DeleteAsync().ConfigureAwait(false);
                        await Interactive.ReplyAndDeleteAsync(Context, _options.Stop.Name);
                        return;
                    }
                    page = request;
                    _    = response.DeleteAsync().ConfigureAwait(false);
                    await RenderAsync().ConfigureAwait(false);
                });
            }
            else if (emote.Equals(_options.Info))
            {
                await Interactive.ReplyAndDeleteAsync(Context, _options.InformationText, timeout : _options.InfoTimeout);

                return(false);
            }
            await Message.RemoveMemberReactionAsync(e.User.Id, emote);

            await RenderAsync().ConfigureAwait(false);

            return(false);
        }
Esempio n. 17
0
 private Task OnReactionAdded(object sender, ReactionAddedEventArgs e)
 => ReactService.HandleReactAddedAsync(this, e);
 protected internal virtual ValueTask OnReactionAdded(ReactionAddedEventArgs e)
 => default;